xsl-list
[Top] [All Lists]

RE: finding lowest level in ancestor:: axis

2006-01-26 16:19:48
  Hi

  Is it what you're looking for?

    ~> cat drafts/ancestor.xml
    <!DOCTYPE div1 [
      <!ATTLIST table id ID #IMPLIED>
    ]>
    <div1>
      <p>Some text here</p>
      <div2>
        <p>More text <ref idref="t1"/></p>
        <example>
          <table id='t1'/>
        </example>
      </div2>
    </div1>

    ~> cat drafts/ancestor.xsl
    <xsl:transform
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
        version="1.0">

      <xsl:output method="text"/>

      <xsl:template match="/">
        <xsl:apply-templates select="//ref" mode="one"/>
        <xsl:text>&#10;</xsl:text>
        <xsl:apply-templates select="//ref" mode="two"/>
      </xsl:template>

      <xsl:template match="ref" mode="one">
        <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"/>
        <xsl:value-of select="count($parent)"/>
        <xsl:text> / </xsl:text>
        <xsl:value-of select="$parent/local-name()"/>
      </xsl:template>

      <xsl:template match="ref" mode="two">
        <xsl:variable name="parent"
                      select="id(@idref)/ancestor::*[
                                  self::div1 or self::div2
                                  or self::div3 or self::div4
                                  or self::div5 or self::div6
                                  or self::div7 or self::div8
                                  or self::div9 or self::div10
                                ][1]"/>
        <xsl:value-of select="count($parent)"/>
        <xsl:text> / </xsl:text>
        <xsl:value-of select="$parent/local-name()"/>
      </xsl:template>

    </xsl:transform>

    ~> saxon drafts/ancestor.xml drafts/ancestor.xsl
    Warning: Running an XSLT 1.0 stylesheet with an XSLT
    2.0 processor
    2 / div1
    1 / div2

  BTW, your solution doesn't select only div1, but it's the first node
of the node-set (because no more in the context of the ancestor axis
where it's the last node), so it's the one used to construct your
result.

  Regards,

--drkm


Dan Vint wrote:

I'm trying to build some links between a tag (table, graphic,
illustration) 
and the referencing tag. So I have a <ref> tag that has an idref
attribute 
that can reference these objects anywhere and these objects can
appear 
directly under one of my division tags or they might be inside a
table or 
code or some other lower level structure, ultimately in the link I
want to 
build I need to know the containing division tag which is not always
the 
immediate parent.

So I have a document that looks like:

<div1>
      <p>Some text here</p>
      <div2>
            <p>More text <ref idref="t1'/></p>
              <example>
                      <table id='t1'/>
              </example>
      </div2>
</div1>

I thought the following would work:

<template match="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(generate-id($parent), '.html#', @idref)}">
           Table <xsl:number level="any" from="div1" count="table"
format="1"/>
           <xsl:text> </xsl:text>             
       </a>
</xsl:template>

Instead of finding the first <div2> tag this seems to always locate
the 
highest ancestor in the tree and comes back with the <div1>. 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.

I thought about adding a [1] to each item in the select for the
variable 
but I don't think that changes anything, both the div2 and div1 are
the 
first of that type. I think my only option is to split this select
out into 
a chose statement which would force the order, is there another way
to do 
this instead of:

<xsl:variable name="parent">
     <xsl:choose>
         <xsl:when test="id(@idref)/ancestor::div10">
        <xsl:value-of select="id(@idref)/ancestor::div10"/>
         </xsl:when>
....
</xsl:choose>
</xsl:variable>

thanks
..dan

PS still using XSLT v1

---------------------------------------------------------------------------
Danny Vint

Specializing in Panoramic Images of California and the West
http://www.dvint.com

voice: 510-522-4703

When H.H. Bennett was asked why he preferred to be out
shooting landscapes rather than spending time in his portrait studio:

"It is easier to pose nature and less trouble to please."

http://www.portalwisconsin.org/bennett_feature.cfm

     


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--





        

        
                
___________________________________________________________________________ 
Nouveau : téléphonez moins cher avec Yahoo! Messenger ! Découvez les tarifs 
exceptionnels pour appeler la France et l'international.
Téléchargez sur http://fr.messenger.yahoo.com

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--