Review recursive tree
This is an open discussion with 11 replies, filed under XSLT.
Search
When using templates, it will call either match
or name
. The first one calls the template to a certain node set by using match
, then works through the XML tree. As you are at a position within the XML node tree when calling by name
, it uses the current node level in that call…
Saying that, however, I think this template could give undesired results when there are more than one entry in the categories node. Is the categories node the one that is output by the nested categories extension? or one that you have made yourself with sections and ds’s etc?
Can we see the XML?
Just for reference, Allen wrote an article about Combining Different Template Methods.
So I use both match
and name
which seems to give the desired result.
I don’t use the nested categories extension, so I build the XML myself using sections with a field that links to itself etc.
I have various (nested) categories and it works fine.
Note just to re-state: this code works as expected (unless I’m missing something): I am not trying to debug but trying to figure out if this is the most efficient method and if it can be improved.
The XML is quite simple.
@klaftertief, I posted before seeing your links. Will look into that, thanks.
I find your XSLT to be a bit confusing, especially that name/match
thing you were asking about.
My solution would look like this: http://gist.github.com/582324. It uses only match
and apply-templates
for the loops and recursions.
Additionally, I’ve changed the way you’re finding the children. You should never compare handles
but ids
instead.
Yep, it works fine, and it can be done using both attributes, but it can be done with just using match…
I’ve edited the code, but can’t test it: pastebin link
I’ve commented it too, but just a quick overview here:
- Removed the predicate from the template itself, it’s not needed.
- Applied the templates with the predicates to limit the search for nodes.
Let me know if it works fine, logically it should, but you never know. If you’re happy doing it the way you have it, stick with that! This is just an example of another way…
Dammit, Nils beat me to it!
@klaftertief thanks! That’s actually exactly what I was trying to do. If I understand Allen’s article correctly my method (combining match and named templates) was (apart from some other things) fine.
Nils (Phoque), John: thanks for your input. You’re absolutely right about the handle
vs id
thing: I changed it to check for id
s. Although your method is certainly simpler the problem is that I have no knowledge of the ‘current/previous’ node. This is needed to construct the href
for the link because the $path
needs to become /category/subcategory/#handle
I found no other way of regaining that knowledge without using a named template.
(Allen’s article, as I understand it, is basically all about this advantage)
Anyway, it turns out my current version looks a lot like my original.
Please let me know if I overlook something or if things could be done better. I’m just starting to get to know XSLT and value your feedback.
You could change the following for readability (but it has nothing to do with the logic/implementation, haven’t looked at it).
<xsl:value-of select="$root" /><xsl:text>/</xsl:text><xsl:value-of select="title/@handle" /> <xsl:value-of select="concat($root, '/', title/@handle)" />
Though string concatenation can become quickly unreadable as well.
I found no other way of regaining that knowledge without using a named template
Matching templates accept param
s too. I’ve changed my example to do pass on the URL.
P.S. Man, it’s annoying to type XSLT on your smartphone. :-D
@klaftertief, thanks. Using concat
certainly seems cleaner in this instance.
@Phoque thanks for taking the time and effort to reply on your smartphone. I’ll look into your example.
Create an account or sign in to comment.
I hope it is appropriate to post this in the forum. I’m just learning XSLT so it would be very helpful if some XSLT gurus reviewed a little snippet I use.
The case is that I have nested
category
entries: eachcategory
has aparent
field pointing to theCategory
section.To create a tree of categories I needed a simple recursive XSLT template. First I tried using a named template with
xsl:call-template
andxsl:with-param
elements. Somehow this did not work out (re: ‘scoping’ of the node elements needed).After some more unsuccessful fiddling I tried the following, which works.
Recursive template using
apply-templates
and amatch
attribute.Now, it seems to do all it needs to do, it builds a tree from the top-categories down. However, I’m actually a bit surprised it works. For example: the original
match
attribute seems to be overridden with the current node when the template is recursively called (without a match attribute). Can anybody explain this to me?Are the
match
attributes necessary in both theapply-templates
as well as the template itself?Obviously I would also welcome any improvements.
Thanks. Dave