获取当前节点的所有祖先(Get all ancestors of current node)

我想得到当前节点的所有祖先:

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

编辑2:为dimitre和所有谁有类似的问题

我的问题的所有答案都很好。

只是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

I want to get all ancestors of current node:

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>

Result:

<item title="a">...</item> <item title="b">...</item>

Edit: Answers with axes ancestor are fine. My problem was elsewhere, in 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>

Returns:

bcdx

Edit2: for dimitre and for all who have a similar problem

All the answers to my question were good.

Just XSLT (up) returns to me a strange result and @Mads Hansen corrected me.

FINAL WORKING EXAMPLE:

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>

Returns:

ab

最满意答案

向亚当致敬,以便快速得到第一个答案。

只是添加一些细节:

您列出的预期结果与您的文字不符。 根元素也是祖先节点,文档也是祖先节点。

ancestor::node()

...将按此顺序返回一个序列:

item[@title='b'] item[@title='a'] root元素(又称文档元素) 根节点 /

要获得您列出的具体结果,您需要:

ancestor::item/.

/的效果。 是将订单更改为转发文件订单。 祖先::的本地顺序是反向文档顺序。


更新:在评论Feed中制作的点的插图。

这个样式表(带有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指令另有说明)。

Congradulations to Adam for a very quick first answer.

Just to add a little detail:

Your listed expected result does not match your words. the root element also an ancestor node and the document is also an ancestor node.

ancestor::node()

... will return a sequence in this order:

item[@title='b'] item[@title='a'] the root element (a.k.a. the document element) the root node /

To get the specific result you listed, you need:

ancestor::item/.

The effect of the /. is to change the ordering back to forward document order. The native order of ancestor:: is reverse document order.


Update: Illustration of points made in the comment feed.

This style-sheet (with OP's input)...

<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>

... will output 'ba' illustrating the point that ancestor:: is indeed a reverse axis. And yet this style-sheet ...

<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>

... has the opposite result 'ab' . This is instructive because it shows that in XSLT 1.0 (not so in XSLT 2.0), the brackets remove the reverse nature, and it becomes a document ordered node-set.

The OP has asked about a transform something like....

<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>

This one returns 'ab' (in XSLT 2.0 it would return 'ba'). Why? Because in XSLT 1.0, the xsl:for-each instruction ignores the reverse-ness of the axis and processes in document order (unless an xsl:sort instruction says otherwise).

更多推荐