tags:

views:

327

answers:

5

I hear time and time again about how you should avoid the use of XSLT for-each. That it's your inner imperative programming demon that should be banished.

What's so bad about it?

Does this best practice matter depending on the size of XML (i.e 100 vs 10,000 nodes)?

+2  A: 

Quick answer: XSLT is largely functional in nature, and imperative loops are not very functional.

In general the based way to get the best out of XSLT is to use pattern matching as much as possible (xsl:apply-template rather than loops, ifs and call-template1).

In the end, it is all about style, and will make little difference in short pieces of XSLT, but being more functional will help with longer/complex problems.

1 Other than when creating functions which return values rather than modifying the output.

Richard
There is nothing "imperative" in <xsl:for-each>. Also, what do you mean by "use-template"? There is no such instruction in XSLT.
Dimitre Novatchev
s/use-template/call-template/: Typo
Richard
looping (or any type) is very much the realm of imperative programming. Functionally one would use recursion.
Richard
This is not exactly true. See the "for expression in XQuery" -- Phill Wadler was one of the main figures behind this language (also one of the fathers of Haskell), Haskell's list comprehension, ..., etc.
Dimitre Novatchev
Also the forM function of the Monad typeclass in Haskell is nothing but a "foreach(list-of-items) function-acting-on-an-item" construct:http://comonad.com/ghc-base/base/Control-Monad.html#v%3AforM
Dimitre Novatchev
+1  A: 

By using apply-templates, perhaps with a mode, makes it easier to include appropriate transformations of more kinds of elements that may be of interest at that location.

For example if you had XML containing a libraries contents, and you keep using for-each all over the place to select books, then you start keeping record of DVDs, CDs, Ginger Nut biscuits, etc, you will have to examine all the for-each sections to include more than just books. If you had used apply-templates, you may be able to simply create the new matches for the new elements.

Stephen Denne
+5  A: 

Templates tend to split up the code more nicely. Also, for-each loops suffer from the fact that people often come to them with the idea that they operate identically to the way for loops work in the major programming languages.

dommer
+1  A: 

It is the use of a for-each to call templates that is discouraged, not the widespread use of for-each, per se. Even the Muenchian method of grouping relies on xsl:key constructs with xsl:for-each loops.

The idea of writing good XSLT is that the structure of your XML should dictate what templates are matched and then applied. Therefore, whenever possible, use apply-templates to select the nodes, rather than applying a select using for-each.

Cerebrus
+5  A: 

Essential difference between <xsl:apply-templates> and <xsl:-for-each> that nobody has pointed out:

  1. <xsl:apply-templates> is really something much more than a nicer, more elegant equivalent of <xsl:for-each>:

xsl:apply-templates is much richer and deeper than xsl:for-each, even simply because we don't know what code will be applied on the nodes of the selection -- in the general case this code will be different for different nodes of the node-list.

Also, the code that will be applied can be written way after the xsl:apply templates was written and by people that do not know the original author.


_2. On the other side, using <xsl:for-each> is in no way harmful if one knows exactly how an <xsl:for-each> is processed.

The trouble is that a lot of newcomers to XSLT that have experience in imperative programming take <xsl:for-each> as a substitute of a "loop" in their favorite PL and think that it allows them to perform the impossible -- like incrementing a counter or any other modification of an already defined <xsl:variable>.

One indispensable use of <xsl:for-each> is to change the current document -- this is often needed in order to be able to use the key() function on a document, different from the current source XML document, for example to efficiently access lookup-table that resides in its own xml document.

Dimitre Novatchev