我想获得当前节点的所有祖先:
XML:
<root>
<item title="a">
<item title="b">
<item title="c"></item> <!--CURRENT-->
<item title="d"></item>
</item>
<item title="x">
<item title="y"></item>
<item title="z"></item>
</item>
</item>
</root>
结果:
<item title="a">...</item>
<item title="b">...</item>
编辑: 轴祖先的答案很好。 我的问题出在其他地方,在XSLT中
XSLT:
<xsl:variable name="curr" select="//item[@title = 'c']"></xsl:variable>
<xsl:variable name="test" select="$curr/ancestor::item"></xsl:variable>
<xsl:for-each select="$test/item">
<xsl:value-of select="@title"></xsl:value-of>
</xsl:for-each>
返回:
bcdx
Edit2:
我的问题的所有答案都很好。
只是XSLT(up)给我一个奇怪的结果,而@Mads Hansen纠正了我。
最终工作示例:
XML:
<?xml version="1.0" encoding="utf-8"?>
<root>
<item title="a">
<item title="b">
<item title="c"></item>
<item title="d"></item>
</item>
<item title="x">
<item title="y"></item>
<item title="z"></item>
</item>
</item>
</root>
XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:variable name="curr" select="//item[@title = 'c']"></xsl:variable>
<xsl:variable name="test" select="$curr/ancestor::item"></xsl:variable>
<xsl:for-each select="$test">
<xsl:value-of select="@title"></xsl:value-of>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
返回:
ab
答案 0 :(得分:5)
向Adam致以最快速的第一个答案。
您列出的预期结果与您的字词不符。根元素也是祖先节点,文档也是祖先节点。
ancestor::node()
...将按此顺序返回一个序列:
item[@title='b']
item[@title='a']
root
元素(a.k.a。文档元素)/
要获得列出的具体结果,您需要:
ancestor::item/.
/的效果。是将订购更改回转发文件订单。祖先::的本机顺序是反向文档顺序。
此样式表(带OP输入)......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//item[@title='c']">
<xsl:value-of select="ancestor::item[1]/@title" />
<xsl:value-of select="ancestor::item[2]/@title" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
...将输出'ba',说明祖先::确实是反向轴的点。然而这个样式表......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//item[@title='c']">
<xsl:value-of select="(ancestor::item/@title)[1]" />
<xsl:value-of select="(ancestor::item/@title)[2]" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
......结果相反'ab'。这是有启发性的,因为它表明在XSLT 1.0中(在XSLT 2.0中不是这样),括号删除了反向性质,它变成了文档有序节点集。
OP已经询问了类似......的变换。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//item[@title='c']">
<xsl:for-each select="ancestor::item">
<xsl:value-of select="@title" />
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这个返回'ab'(在XSLT 2.0中它将返回'ba')。为什么?因为在XSLT 1.0中,xsl:for-each指令忽略了轴的反向性并按文档顺序处理(除非xsl:sort指令另有说明)。
答案 1 :(得分:3)
我想获得当前节点的所有祖先
指定的节点显然不是“绿色”节点的所有祖先。
选择所有祖先使用:
ancestor::node()
这将选择初始conext节点(或当前节点)的所有祖先节点,包括顶部元素及其父元素 - root node /
- 这是一个节点,但不是一个元素。
选择所有元素祖先使用:
ancestor::*
这与前一个表达式类似,但不选择root node(/
),因为它不是元素。
要选择名为item
的所有祖先,请使用:
ancestor::item
请注意:以上所有表达式都假设(//item[@title='c'])[1]
是初始上下文节点(当前节点)。如果此假设不正确,则必须在每个表达式前加(//item[@title='c'])[1]/
。
Note2 :我强烈建议学习XPath以使用 the XPath Visualizer 等工具。多年来,这个工具帮助成千上万的人学习XPath的有趣方式 - 通过使用XPath表达式并观察他们的评估结果。
注意:XPath Visualizer是我在2000年创建的,从来不是一个金融产品。我建议它完全基于它对用户的价值,经过多年的证明
答案 2 :(得分:2)
您可以使用xpath ancestor::item
答案 3 :(得分:1)
您输出bcdx
而不是ab
的原因是因为您的<xsl:for-each>
正在迭代所选item
元素的所有item
个子元素,而不是仅仅迭代$test
变量中的选定元素。
将您的for-each更改为仅对$test
进行迭代:
<xsl:variable name="curr" select="//item[@title = 'c']"></xsl:variable>
<xsl:variable name="test" select="$curr/ancestor::item"></xsl:variable>
<xsl:for-each select="$test">
<xsl:value-of select="@title"></xsl:value-of>
</xsl:for-each>