我有一个XML文档,其中包含chapters
和嵌套sections
。我试图为任何部分找到第一个二级部分祖先。这是ancestor-or-self
轴中的倒数第二部分。伪代码:
<chapter><title>mychapter</title>
<section><title>first</title>
<section><title>second</title>
<more/><stuff/>
</section>
</section>
</chapter>
我的选择器:
<xsl:apply-templates
select="ancestor-or-self::section[last()-1]" mode="title.markup" />
当然,这在未定义 last()-1 之前有效(当前节点是 first
部分)。
如果当前节点位于second
部分下方,我希望标题second
.否则我想要标题first
.
将你的 xpath 替换为:
ancestor-or-self::section[position()=last()-1 or count(ancestor::section)=0][1]
由于您已经可以在除一种以外的所有情况下找到正确的节点,因此我更新了您的 xpath 以找到first
部分 ( or count(ancestor::section)=0
),然后选择 ( [1]
) 第一个匹配项(以相反的文档顺序,因为我们使用的是ancestor-or-self
轴)。
这是一个更短、更高效的解决方案:
(ancestor-or-self::section[position() > last() -2])[last()]
这将选择可能前两个最顶级祖先中的最后一个名为 section
。如果只有一个这样的祖先,那么它本身就是最后一个。
这是一个完整的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="section">
<xsl:value-of select="title"/>
<xsl:text> --> </xsl:text>
<xsl:value-of select=
"(ancestor-or-self::section[position() > last() -2])[last()]/title"/>
<xsl:text>
</xsl:text>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
当此转换应用于以下文档时(基于提供的,但添加了更多嵌套section
元素):
<chapter>
<title>mychapter</title>
<section>
<title>first</title>
<section>
<title>second</title>
<more/>
<stuff/>
<section>
<title>third</title>
</section>
</section>
</section>
</chapter>
将产生正确的结果:
first --> first
second --> second
third --> second