[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: backwards tree-traversal algorithm?

Subject: Re: backwards tree-traversal algorithm?
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Wed, 23 Oct 2002 18:48:18 +0100
xsl for each backwards
Hi John,

> since i am doing (i believe it is called) "push-based" processing
> rather than pull, how would i specify which node is my starting
> node?

Your starting node is automatically the current node:

  <xsl:for-each select="ancestor::*">
    ...
  </xsl:for-each>

is the same as:

  <xsl:for-each select="current()/ancestor::*">
    ...
  </xsl:for-each>

If you have a node held in a variable, then use that instead of
current():

  <xsl:for-each select="$current/ancestor::*">
    ...
  </xsl:for-each>

> i make document() calls to an xml file "dirs.xml" containing an xml
> representation of the directory structure where the source document
> is located. the reason that i want to iterate over the ancestor
> nodes is that i am doing a "breadcrumbs" sort of thing, where i want
> to show what the progression of parent nodes was in the tree.
>
> at transformation time, the stylesheet gets a set of parameters from
> the command line: $parent0, $parent1, $parent2, etc. which contain
> the directory names of the preceding directories, and a $depth param
> which contains the depth of the file in the structure, eg.
>
> sab sheet.xsl /foo/bar/baz/file.xml $depth=3 $parent0=foo $parent1=bar $parent3=baz $depth=3
>
> i then use those parameters to create a nodeset variable pointing to
> the node within dirs.xml which corresponds to the location of the
> source document in the filesystem.
>
> eg. i have a variable called $current, defined as follows:
>
> <xsl:variable name="current">
>   <xsl:choose>
>     <xsl:when test="$depth=1"><xsl:copy-of select="document($d)/root/section" /></xsl:when>
>     <xsl:when test="$depth=2"><xsl:copy-of select="document($d)/root/section[@id=$parent0]/section" 
>     <xsl:when test="$depth=3"><xsl:copy-of select="document($d)/root/section[@id=$parent0]/section[@id=$parent1]/section" 
>                 ...
>                 <xsl:otherwise> no logic coded for this level of hierarchy </xsl:otherwise>
>   </xsl:choose>
> </xsl:variable>
>
> this obviously seems very crude because it puts a strict upper bound
> on how deep the hierarchy can go, and it's really redundant. but
> when i initially passed in the location path as a string, eg.
>
> sab sheet.xsl /foo/bar/baz/file.xml $location=/foo/bar/baz/file.xml
>
> and tried to turn $location into an xpath expression, i fell on my
> face because it's not possible to construct xpath on fly in XSL.

I'm not sure I'm following all the details, but you can use recursion
to work through the $location parameter as you work through the tree.
Something like:

<xsl:template match="/">
  <xsl:apply-templates select="document($d)/root" mode="find">
    <xsl:with-param name="loc"
                    select="substring-after($location, '/')" />
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="find">
  <xsl:param name="loc" />
  <xsl:choose>
    <xsl:when test="contains($loc, '/')">
      <xsl:apply-templates mode="find"
          select="section[@id = substring-before($loc, '/')]">
        <xsl:with-param name="loc"
                        select="substring-after($loc, '/')" />
      </xsl:apply-templates>
    </xsl:when>
    <xsl:otherwise>
      <!-- got to the file name -->
      <xsl:apply-templates select="section" mode="process" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

<xsl:template match="section" mode="process">
  <xsl:copy-of select="." />
</xsl:template>

If you want to do something other than copy the section elements that
are children of the one representing the directory in which the file
is held, replace the content of the process-mode template.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.