RE: grabbing the path to a particular node

Subject: RE: grabbing the path to a particular node
From: Richard Lander <rlander@xxxxxxxxxxxxx>
Date: Tue, 8 Aug 2000 14:10:06 -0700
 Jeni,

Thanks for the help. Your solution is smart and simple. I did build a *long*
solution, which produces the same results, but it is about 50 lines and
likely very inefficent. I like your solution very much and it makes a good
deal of sense.

Thanks,

Rich

-----Original Message-----
From: Jeni Tennison [mailto:jeni.tennison@xxxxxxxxxxxxxxxx]
Sent: Tuesday, August 08, 2000 2:08 AM
To: Richard Lander
Cc: 'xsl-list@xxxxxxxxxxxxxxxx'
Subject: RE: grabbing the path to a particular node


Rich,

>I'm actually building the template now. Unless I've missed an easier
design,
>one basically has to walk the tree up to the root node, to grab the
location
>path. At that point, the location path is in reverse, so one must write
>another recursive template to switch the order. That's the part I'm doing
>now, as the first part was pretty easy.

It only constructs it in the wrong order if you recurse in the wrong place.
 If you do:

<xsl:template match="*" mode="path">
  <xsl:text>/</xsl:text>
  <xsl:value-of select="name()" />
  <xsl:apply-templates select="parent::*" mode="path" />
</xsl:template>

or something similar, then you are outputting the step for each parent
*after* the step for its child, so the path is the wrong way round.  If, on
the other hand, you do:

<xsl:template match="*" mode="path">
  <xsl:apply-templates select="parent::*" mode="path" />
  <xsl:text>/</xsl:text>
  <xsl:value-of select="name()" />
</xsl:template>

then you generate the information for the parent before the information for
the child, which gives you the hierarchy that you want.

It is actually possible to do this without recursion because the
ancestor-or-self axis gives you a list of the nodes that are ancestors of
the current node (or the current node itself).  You can *iterate* over this
list instead:

<xsl:for-each select="ancestor-or-self::*">
  <xsl:text>/</xsl:text>
  <xsl:value-of select="name()" />
</xsl:for-each>

You only need to do recursion when the hierarchy path that you're
constructing is not the same as the hierarchy path that you have in your
source.  This happens when, for example, you have a flat structure
describing a number of classes each of which have attributes giving links
to the parent class.

In addition you should bear in mind that the paths you create using this
method do not give you exact directions to the node that you want.  To do
so, you should add predicates to the path indicating the position of the
node relative to those of its siblings with the same name or use some other
method to identify the unique properties of a particular element (e.g. the
value of an attribute, particularly an ID attribute).

I hope this helps,

Jeni

Dr Jeni Tennison
Epistemics Ltd, Strelley Hall, Nottingham, NG8 6PE
Telephone 0115 9061301 * Fax 0115 9061304 * Email
jeni.tennison@xxxxxxxxxxxxxxxx


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


Current Thread