Re: xsl:apply-templates Q

Subject: Re: xsl:apply-templates Q
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 1 Nov 2000 10:02:11 -0400 (EST)
Maulik,

>My XSL snippet is:
>
><xsl:template match="/">
>
>some testing...and tables...
>
><xsl:apply-templates select="//Date" />
></xsl:template>
>
>I want the <xsl:apply-templates> to only select the main <Date> element and
>not the <Date> element within the <Weeks> node.  Unfortunately I have no
>control over the XML file. Any help is appreciated.

If you look at your xsl:apply-templates, it's selecting:

  //Date

which expands to:

  /descendant-or-self::node()/Date

This says "from the root node, select all nodes that are descendants of the
root node and the root node itself, and then select all the children of
those nodes that are elements called 'Date'".  In other words, it selects
all the descendants of the root node that are 'Date' elements - all the
'Date' elements in the document.

If you want to only select the *main* Date element, then you can do two
things.  The first is probably much better (in that it takes less
processing because it builds a far smaller intermediate node list), as long
as you know, from the root node, how to get to the Date element you're
interested in.  If you do, then you can step down the element hierarchy to
point to the Date element:

  /data/Dates/Date

In fact, given that this select expression is within a root-node-matching
template, you can leave off the '/' at the beginning: the current node is
the root node, so there's no need to explicitly start at the root node
within the XPath:

  data/Dates/Date

If you *don't* know the hierarchy down to the Date, but only know that the
Date elements you're interested in are not children of a 'Weeks' element,
you could select all the Date elements as you have, and then filter that
list using a predicate to pick only those Date elements that are not within
a Weeks element:

  //Date[not(parent::Weeks)]

A slightly better rendition of this (because, again, it builds shorter
intermediate node lists) is:

  /descendant-or-self::node()[not(self::Weeks)]/Date

which says "from the root node, select all nodes that are descendants of
the root node and the root node itself, and that aren't elements called
'Weeks', and then select all the children of those nodes that are elements
called 'Date'".

[If you know that the Date is not the document element (i.e. the top-most
element in the tree), then you could alternatively use:

  /descendant::*[not(self::Weeks)]/Date

i.e. "from the root node, select all elements that are not elements called
'Weeks', and then select all the children of those elements that are
elements called 'Date'"]

I hope that this helps by showing you some of the options that are
available to you.

Cheers,

Jeni

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




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


Current Thread