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

Re: recursive template grabbing nested elements...

Subject: Re: recursive template grabbing nested elements...
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Sun, 15 Jul 2001 09:30:18 +0100
nested xsl template
Hi Anthony,

> i want to have a recursive template that finds the deepest <tab>
> with state="on", and then grabs the preceding sibling and the
> following siblings' (or parent's sibling) "id" attribute.

Once you've found the deepest tab element, you can output whatever you
want within a template for it, e.g.:

<xsl:template match="tab">
  current = <xsl:value-of select="@id" />
  prev = <xsl:value-of select="preceding-sibling::tab/@id" />
  next = <xsl:value-of
           select="following-sibling::tab/@id |
                   ../following-sibling::tab
                        [not(current()/following-sibling::tab)]/@id" />
</xsl:template>

[Note that this doesn't get the parent's following

You can work out the depth of an element by counting how many
ancestors it has:

  count(ancestor::*)

So finding the deepest tab element involves finding a calculated
maximum and applying templates to the tab element that has that
maximum. I would use a template like the following, which works
through the tab elements by applying templates to them. If there's a
following tab with a state of on that's more deeply nested, then the
template moves on to that tab. Otherwise, it applies the template
above to this tab element:

<xsl:template match="tab" mode="deepest">
  <xsl:variable name="depth" select="count(ancestor::*)" />
  <xsl:variable name="next"
                select="following::tab[@state = 'on']
                          [count(ancestor::*) > $depth]" />
  <xsl:choose>
    <xsl:when test="$next">
      <xsl:apply-templates select="$next" mode="deepest" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="." />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

You would call this template by applying templates to the first
descendant tab element with a state of 'on', in 'deepest' mode:

  <xsl:apply-templates select=".//tab[@state = 'on'][1]"
                       mode="deepest" />

Alternatively, you could use a more traditionally recursive template
into which you pass all the tab elements that you might be interested
in:

  <xsl:call-template name="deepest">
    <xsl:with-param name="tabs" select=".//tab[@state = 'on']" />
  </xsl:call-template>

The template to handle this would keep track of the deepest tab found
thus far and compare it to the first in the $tabs list. The new
deepest tab is passed in to the next recursion of the template, if
there are more tab elements left in the list to go through, or has
templates applied to it if not.

<xsl:template name="deepest">
  <xsl:param name="tabs" />
  <xsl:param name="deepest" select="/.." />
  <xsl:variable name="new-deepest"
                select="count($tabs[1]/ancestor::*) >
                        count($deepest/ancestor::*)" />
  <xsl:choose>
    <xsl:when test="$tabs[2]">
      <xsl:call-template name="deepest">
        <xsl:with-param name="tabs" select="$tabs[position() > 1]" />
        <xsl:with-param name="deepest"
                        select="$tabs[1][$new-deepest] |
                                $deepest[not($new-deepest)]" />
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="$new-deepest">
      <xsl:apply-templates select="$tabs[1]" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="$deepest" />
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

I should think Dimitre will show you an alternative that is not as
closely coupled with your source XML, using one of his generic
templates.

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.