XPath 1.0最接近的前一个和/或祖先节点,其中包含XML树中的属性

the*_*arv 20 xml xslt xpath

这是三个XML树

(1)

<?xml version="1.0" encoding="UTF-8"?>
<content>
   <section id="1">
        <section id="2"/>
        <section id="3"/>
        <section id="9"/>
    </section>
    <section id="4">
        <section id="5">
            <section>
                <bookmark/> <!-- here's the bookmark-->
                <section id="6">
                    <section id="7">
                        <section id="8"/>
                    </section>
               </section>
            </section>
        </section>
    </section>
</content>
Run Code Online (Sandbox Code Playgroud)

(2)

<?xml version="1.0" encoding="UTF-8"?>
<content>
    <section id="1"/>
    <section id="2">
        <section id="9">
            <section id="10">
                <section id="11"/>
            </section>            
        </section>
        <section>
            <section id="4">
                <section id="5"/>
            </section>            
        </section>
        <section/>
        <bookmark/> <!-- here's the bookmark-->
        <section id="6">
            <section id="7">
                <section id="8"/>
            </section>
        </section>
    </section>
</content>
Run Code Online (Sandbox Code Playgroud)

在两种情况下,期望的结果是id 5.

使用XSLT 1.0和XPath 1.0,我可以从(1)获得祖先

<xsl:value-of select="//bookmark/ancestor::*[@id][1]/@id"/>
Run Code Online (Sandbox Code Playgroud)

或者(2)的前一个节点

<xsl:value-of select="//bookmark/preceding::*[@id][1]/@id"/>
Run Code Online (Sandbox Code Playgroud)

如何使用书签中的id 获取最近的祖先前一节点?
我需要一个xsl:value-of匹配两种情况.谢谢.

编辑:

解决方案也应该涵盖这种结构.期望的身份仍然是5.

(3)

<?xml version="1.0" encoding="UTF-8"?>
<content>
   <section id="1">
        <section id="2"/>
        <section id="3"/>
        <section id="9"/>
    </section>
    <section id="4">
        <section>
            <section id="10"/>
            <section id="5"/>
            <section>
                <bookmark/> <!-- here's the bookmark-->
                <section id="6">
                    <section id="7">
                        <section id="8"/>
                    </section>
                </section>
            </section>
        </section>
    </section>
</content>
Run Code Online (Sandbox Code Playgroud)

Dim*_*hev 24

用途:

    (//bookmark/ancestor::*[@id][1]/@id 
| 
    //bookmark/preceding::*[@id][1]/@id
     )
     [last()]
Run Code Online (Sandbox Code Playgroud)

验证:使用XSLT作为XPath的主机,进行以下转换:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:value-of select=
  "(//bookmark/ancestor::*[@id][1]/@id
  |
   //bookmark/preceding::*[@id][1]/@id
   )
    [last()]"/>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

当应用于任何提供的三个XML文档时,产生想要的,正确的结果:

5

我强烈建议使用XPath Visualizer来玩/学习XPath.