Re: [xsl] finding lowest level in ancestor:: axis

Subject: Re: [xsl] finding lowest level in ancestor:: axis
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Jan 2006 17:59:19 -0500
At 2006-01-26 13:56 -0800, Dan Vint wrote:
in the link I want to build I need to know the containing division tag which is not always the immediate parent.
...
Instead of finding the first <div2> tag this seems to always locate the highest ancestor in the tree and comes back with the <div1>.

Right ... because although the steps in the location path are addressed in proximity order, the set of nodes returned is addressed in document order, and generate-id() always acts on the first in document order.


I even changed the order of the select for the variable to be high to low and low to high and nothing changed. I though maybe there might be an evaluation order going on.

There isn't.


is there another way to do this instead of:

You were very close ... having selected all the ancestors, you know the result set is going to be in a direct line from the id() node to the root of the tree ... to get the closest, all you need is the last of those in document order, so use [last()] on the set.


Below is code that has your code first (returning div1), the addition of the predicate second (returning div2), and perhaps an abbreviated expression that might be of interest (also returning div2). Note that I changed generate-id() to name() in order to expose to which node I am pointing.

Note that your tables won't be numbered until you change your current node to the id()'ed node (which I did in the third example).

I hope this helps, Dan.

. . . . . . . . . . . Ken

T:\ftemp>type dan.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE div1
[
  <!ATTLIST table id ID #REQUIRED>
]>
<div1>
     <p>Some text here</p>
     <div2>
           <p>More text <ref idref='t1'/></p>
             <example>
                     <table id='t1'/>
             </example>
     </div2>
</div1>

T:\ftemp>type dan.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
  <xsl:for-each select="//ref">
    <xsl:variable name="parent"
           select="(id(@idref)/ancestor::div10 |
                    id(@idref)/ancestor::div9 |
                    id(@idref)/ancestor::div8 |
                    id(@idref)/ancestor::div7 |
                    id(@idref)/ancestor::div6 |
                    id(@idref)/ancestor::div5 |
                    id(@idref)/ancestor::div4 |
                    id(@idref)/ancestor::div3 |
                    id(@idref)/ancestor::div2 |
                    id(@idref)/ancestor::div1)"/>
     <a href="{concat(name($parent), '.html#', @idref)}">
          Table <xsl:number level="any" from="div1" count="table" format="1"/>
          <xsl:text> </xsl:text>
     </a>
  </xsl:for-each>
  <xsl:for-each select="//ref">
    <xsl:variable name="parent"
           select="(id(@idref)/ancestor::div10 |
                    id(@idref)/ancestor::div9 |
                    id(@idref)/ancestor::div8 |
                    id(@idref)/ancestor::div7 |
                    id(@idref)/ancestor::div6 |
                    id(@idref)/ancestor::div5 |
                    id(@idref)/ancestor::div4 |
                    id(@idref)/ancestor::div3 |
                    id(@idref)/ancestor::div2 |
                    id(@idref)/ancestor::div1)[last()]"/>
     <a href="{concat(name($parent), '.html#', @idref)}">
          Table <xsl:number level="any" from="div1" count="table" format="1"/>
          <xsl:text> </xsl:text>
     </a>
   </xsl:for-each>
  <xsl:for-each select="//ref">
    <xsl:variable name="parent"
           select="(id(@idref)/ancestor::*[starts-with(local-name(),'div')])
                   [last()]"/>
     <a href="{concat(name($parent), '.html#', @idref)}">
       <xsl:for-each select="id(@idref)">
          Table <xsl:number level="any" from="div1" count="table" format="1"/>
          <xsl:text> </xsl:text>
        </xsl:for-each>
     </a>
   </xsl:for-each>
</xsl:template>

</xsl:stylesheet>
T:\ftemp>xslt dan.xml dan.xsl con
<?xml version="1.0" encoding="utf-8"?>
<a href="div1.html#t1">
          Table  </a>
<a href="div2.html#t1">
          Table  </a>
<a href="div2.html#t1">
          Table 1 </a>
T:\ftemp>


-- Upcoming XSLT/XSL-FO hands-on courses: Denver,CO March 13-17,2006 World-wide on-site corporate, govt. & user group XML/XSL training. G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995) Male Cancer Awareness Aug'05 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread