Search

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: each category has a parent field pointing to the Category section.

To create a tree of categories I needed a simple recursive XSLT template. First I tried using a named template with xsl:call-templateand xsl: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 a match 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 the apply-templates as well as the template itself?

Obviously I would also welcome any improvements.

Thanks. Dave

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:

  1. Removed the predicate from the template itself, it’s not needed.
  2. 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 ids. 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 params 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.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details