开发者

How to get the nearest ancestor or child of an ancestor with xpath

开发者 https://www.devze.com 2023-03-16 16:56 出处:网络
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

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"/>
0

精彩评论

暂无评论...
验证码 换一张
取 消