How to get the nearest ancestor or child of an ancestor with xpath
Look at <bookmark/>
. The desired output I want is the id with value 5
<xsl:value-of select="//bookmark/ancestor::*[@id][1]/@id"/>
only gives me 4
<?xml version="1.0" encoding="UTF-8"?>
<content>
<section id="1">
<section id="2"/>
<section id="3"/>
<section id="9"/>
</sect开发者_C百科ion>
<section id="4">
<section>
<section id="10"/>
<section id="5"/>
<section>
<bookmark/>
<section id="6">
<section id="7">
<section id="8"/>
</section>
</section>
</section>
</section>
</section>
</content>
The way I understand the question and the provided XML document is that the nearest id
attribute can also happen on an ancestor (section
) element.
In any such case the expressions using ony the preceding::
axis (as specified in the other answers to this question) don't select any node.
One correct XPath expression, which selects the wanted id
attribute is:
(//bookmark/ancestor::*[@id][1]/@id
|
//bookmark/preceding::*[@id][1]/@id
)
[last()]
If the id
attribute is also allowed on the bookmark
element itself, the above XPath expression needs to be modified slightly to accomodate this:
(//bookmark/ancestor-or-self::*[@id][1]/@id
|
//bookmark/preceding::*[@id][1]/@id
)
[last()]
Do note: The ancestor::
and the preceding::
axes do not intersect (do not overlap).
section[@id=5]
is not an ancestor of <bookmark>
, but it is preceding it.
The ancestor axis contains the ancestors of the context node; the ancestors of the context node consist of the parent of context node and the parent's parent and so on; thus, the ancestor axis will always include the root node, unless the context node is the root node
The preceding axis contains all nodes in the same document as the context node that are before the context node in document order, excluding any ancestors and excluding attribute nodes and namespace nodes
Change ancestor::
to preceding::
:
//bookmark/preceding::*[@id][1]/@id
Use the preceding axis:
<xsl:value-of select="//bookmark/preceding::*[@id][1]/@id"/>
精彩评论