XSLT:除特定类型之外的任何深度的最后一个元素

时间:2014-03-07 14:08:43

标签: xml xslt

使用XSLT 1我想从XML文档中选择任何深度的最后一个节点,该节点直接包含在特定类型中,但本身并不是该类型。

例如:

<root>
<div>
    <p>A node</p>
</div>
<div>
    <p>Another node</p>
    <div>
        <p>A third node</p>
        <div>
            <p>A fourth node</p>
            <p>The node <span>sub-element</span> that I want</p>
        </div>
    </div>
</div>
</root>

我想得到&lt; p&gt;节点&lt; span&gt;子元素&lt; / span&gt;我想要&lt; / p&gt;在这种情况下(重写这个具体案例的问题):

选择div直接包含的任何深度的最后一个节点,但本身不是div。

答案应该可以抽象到任何深度(即不是“/ div / div / div / p”)

&lt; span&gt;不应选择节点,因为其父节点不是div

对此有任何帮助表示感谢!

1 个答案:

答案 0 :(得分:3)

你应该能够得到你想要的东西

(//div/*[not(self::div)])[last()]

//div/*[not(self::div)]为您提供文档中任何位置div的直接子项的元素,并且它们本身不是div[last()]选择最后一个元素这些按文件顺序排列。由于孩子被认为是按照文件顺序追随父母,因此您可以确定所选元素不会有任何自己有子女的div后代。

括号很重要,如果省略它们,那么你会得到一个非常不同的表达式

//div/*[not(self::div)][last()]

将为您提供一个序列,其中包含所有级别文档中每个div的最后一个非div元素子元素(即[last()]仅适用于该文档中的最后一步路径而不是整个路径。)


琐碎的XSLT示例:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <xsl:copy-of select="(//div/*[not(self::div)])[last()]" />
  </xsl:template>
</xsl:stylesheet>

输出:

<?xml version="1.0"?>
<p>The node <span>sub-element</span> that I want</p>