xslt - XPath 1.0 closest preceding and/or ancestor node with an attribute in a XML Tree -


here 3 xml-trees

(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 bookmark-->                 <section id="6">                     <section id="7">                         <section id="8"/>                     </section>                </section>             </section>         </section>     </section> </content> 

(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 bookmark-->         <section id="6">             <section id="7">                 <section id="8"/>             </section>         </section>     </section> </content> 

the desired result in both cases id 5.

with xslt 1.0 , xpath 1.0 can either ancestor (1)

<xsl:value-of select="//bookmark/ancestor::*[@id][1]/@id"/> 

or preceding node (2)

<xsl:value-of select="//bookmark/preceding::*[@id][1]/@id"/> 

how nearest ancestor or preceding node id bookmark?
need single xsl:value-of matches both cases. thanks.

edit:

the solution should cover structure. desired id still 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 bookmark-->                 <section id="6">                     <section id="7">                         <section id="8"/>                     </section>                 </section>             </section>         </section>     </section> </content> 

use:

    (//bookmark/ancestor::*[@id][1]/@id  |      //bookmark/preceding::*[@id][1]/@id      )      [last()] 

verification: using xslt host of xpath, following transformation:

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

when applied on of provided 3 xml documents, produces wanted, correct result:

5

i recomment using xpath visualizer playing / learning xpath.


Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -