Re: [xsl] recursive problem with full path and position info

Subject: Re: [xsl] recursive problem with full path and position info
From: Dan Diebolt <dandiebolt@xxxxxxxxx>
Date: Sun, 29 Apr 2001 18:02:30 -0700 (PDT)
Thanks Jeni. The speed was much better descending from the top. To 
the others that may have read over this thread, Jeni showed a very 
interesting technique worth pointing out: parameters can be used 
with <xsl:apply-templates .../> just as easily as it is with the
more common <xsl:call-templates .../> uasge. The use of paramaters
with <xsl:apply-templates .../> may in some cases be prefered to
near duplicate templates invoked under differnet modes as you
might do for debug, or comparisons, or tutorial examples. It is
worth experimenting with. Is anyone else using this technique?



--- Jeni Tennison <mail@xxxxxxxxxxxxxxxx> wrote:
> Hi Dan,
> > How would you approach this problem? I do not know *any* of the tag
> > names ahead of time. I have an approach that works which matches on
> > the leaf nodes with child::*[not(child::*)] and crawls up, but it is
> > very slow and I don't think it is the correct approach. I think I
> > need a strategy that matches from the top and decends.
> That's a reasonable approach, and it's the one that I'd use most of
> the time when I want to get a path because often you want to target a
> path to a particular node. If you're getting paths for all the leaf
> nodes, as you are in your case, it has the disadvantage that you
> revisit nodes higher in the node tree multiple times, which is why
> it's slow.
> With the descending approach, you only visit each node once, but you
> need to pass down a string holding the path information about the
> ancestor nodes.  One way would be a default element-matching template
> that just applied templates to element children, adding its own
> information to the path:
> <xsl:template match="*">
>    <xsl:param name="path" />
>    <xsl:apply-templates select="*">
>       <xsl:with-param name="path"
>          select="concat($path, name(), '(', position(), ').')" />
>    </xsl:apply-templates>
> </xsl:template>
> And then another template for elements at the bottom of the node tree,
> which outputs the path that it's got from its parent, plus its own
> information, and then the value as you desired.
> <xsl:template match="*[not(*)]">
>    <xsl:param name="path" />
>    <xsl:value-of select="$path" />
>    <xsl:value-of select="name()" />(<xsl:value-of select="position()" />
>    <xsl:text>) = '</xsl:text>
>    <xsl:value-of select="." />'
<xsl:text />
> </xsl:template>
> I wasn't sure about the numbering that you were using - in the above,
> the number represents the index of the element child within its
> parent. You may be after the index of the element within its siblings
> with the same name, in which case you could use xsl:number or count
> them with:
>   count(preceding-sibling::*[name() = name(current())])
> I hope that helps,
> Jeni
> ---
> Jeni Tennison

Do You Yahoo!?
Yahoo! Auctions - buy the things you want at great prices

 XSL-List info and archive:

Current Thread