What's so bad about xsl:for-each? - xslt

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)?

Essential difference between <xsl:apply-templates> and <xsl:-for-each> that nobody has pointed out:
<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.

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.

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.

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.

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.

Related

When to use for-each and when to use apply-templates in xslt?

I've heard that most of the time it's usually possible (and better) to use apply-templates rather than for-each when writing an XSLT. Is this true? If so, what are the benefits of using apply-templates?
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> in XSLT 1.0 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.
On the other side, using <xsl:template> and <xsl:apply-templates> is much more powerful and elegant.
Here are some of the most important differences between the two approaches:
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.
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.
The FXSL library's implementation of higher-order functions (HOF) in XSLT wouldn't be possible if XSLT didn't have the <xsl:apply-templates> instruction.
Summary: Templates and the <xsl:apply-templates> instruction is how XSLT implements and deals with polymorphism.
Reference: See this whole thread: http://www.stylusstudio.com/xsllist/200411/post60540.html

differences between for-each and templates in xsl?

Both xsl:for-each and xsl:template are used to retrieve nodes from xml in an xsl stylesheet. But what is the fundamental difference between them? Please guide me. Thanks in advance.
I generally agree with the other answers, but I will say that in my experience, a stylesheet written with xsl:for-each can be a lot easier to read, understand, and maintain than one that relies heavily xsl:apply-templates... Especially xsl:apply-templates with an implicit select (or a very generic select like select="node()").
Why? Because it's very easy to see what a for-each will do. With apply-templates, you in essence have to (a) know about all possible XML inputs (which will be easier if you have a schema, but then you still have to digest the schema; and many times you don't have a schema, especially for transient intermediate XML data sent on one stage of a pipeline; and even if you have a schema, your development framework (such as an ESB or CMS) may not give you a way to validate your XML at every point your pipelines. So if invalid data creeps in you will not be notified right away), so you can predict what kinds of nodes will be selected (e.g. children of the context node); and (b) look at every template in the stylesheet to see which template matches those nodes with highest priority (and last in document order). The order of processing may also skip all over the files, or over different files (imported or included). This can make it very difficult to "see" what's going on.
Whereas with a for-each, you know exactly which code will get instantiated: the code inside the for-each. And since for-each requires an explicit select expression, you're more likely to have a narrower field to guess from regarding what nodes can be matched.
Now I'm not denying that apply-templates is much more powerful and flexible than for-each. That's exactly the point: constructs that are more powerful and flexible, are also harder to constrain, understand, and debug (and prevent security holes in). It's the Rule of Least Power: "Powerful languages (or in this case, constructs) inhibit information reuse." (Also discussed here.)
When you use apply-templates, each template is more modular and therefore more reusable in itself, but the stylesheet is more complex and the interaction between templates is less
predictable. When you use for-each, the flow of processing is easy to predict and see.
With <xsl:apply-templates />, (or with <xsl:for-each select="node()"/>), when structure of the input XML changes, the behavior of the stylesheet changes, without the developer's review. Whether this is good or bad depends on how much forethought you've put into your stylesheet, and how much good communication there is between the XML schema developer and the stylesheet developer (who may be the same person or may belong to different organizations).
So to me, it's a judgment call. If you have document-oriented XML, like HTML, where lots of the element types really can have many different types of children, in an arbitrary-depth hierarchy, and the processing of a given element type doesn't depend very often on its context, then apply-templates is absolutely essential. On the other hand if you have "data-oriented" XML, with a predictable structure, where you don't often have the same element type meaning the same thing in different contexts, for-each can be much more straightforward to read and debug (and therefore to write correctly and quickly).
I think this has some what to do with understanding push vs. pull style processing than just comparing xsl:for-each or xsl:template match="...". You often see programmers from another discipline using a lot of xsl:if, xsl:choose and for-loops when the problem could have been solved in a more elegant XSLTish way.
But to the question: In my opinion, if you consider using xsl:for-each instead of processing the data with xsl:apply-templates you need to rethink. There are cases where a for-loop is suitable in XSLT, but whenever a matching template would do the same, templates are the way to go. In my experience, you can usually do most xsl:for-each with an xsl:apply-templates instead.
Some benefits as I see it of using matching templates over a for-loop are:
The stylesheets are easier to maintain and extend especially if source data changes.
As #chiborg mentions, templates can be reused since they are not built into a specific template. Together with xsl:next-match in XSLT 2.0 you can chain templates together in powerful ways.
You don't have to mimic behavior already built in to all XSLT processors, that is; use xsl:apply-templates and let the processor work for you.
Also, I find it easier to understand and debug a push style stylesheet. If you divide your stylesheet info small templates which do one or a few things and write specific matching patterns it's easy to see which template is doing what and trace the source of the problem.
Both the 'for-each' and 'template' are
used to retrieve the nodes from xml in
the xsl. But what is the difference
between them in basically
Here are some of the most important differences:
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.
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.
The FXSL library's implementation of higher-order functions (HOF) in XSLT wouldn't be possible if XSLT didn't have the <xsl:apply-templates> instruction.
Summary: Templates and the <xsl:apply-templates> instruction is how XSLT implements and deals with polymorphism.
Reference: See this whole thread: http://www.stylusstudio.com/xsllist/200411/post60540.html
It doesn't really matter, but you may want to think about it for the following thumb of rules that I found:
If the code depends on the context
position (position()), put it in a
<xsl:for-each>.
If the code depends on the context
node (. or any location path), put it
in a matching template.
Otherwise, use a named template.
Reference and read more at:
http://www.jenitennison.com/blog/node/9
These are to complete different XSLT instructions.
More than push vs. pull style, this is more like iteration vs. recursion.
xsl:for-each is an iterator instruction with all the benefits and constrains of iteration in a stateless declarative paradigm: a good processor should not polute the call stack.
xsl:apply-templates is a general recursion instruction. General in the sense that it's more powerful than xsl:call-template: you "throw" the selected nodes to the pattern matching mechanism, a truly "dynamic function invocation".
for-each can only be used inside one place in your template. Templates can be re-used with different apply-templates calls. I mostly use templates instead of for-each because of the added flexibility.
One use of for-each I haven't seen mentioned: you can use it to switch the context node to another document. I've used it to transform data XML to a HTML input form. The template that matched a data field contained a for-each that selected a single node: the xs:element in the XSD that described the data field to transform.
Using the description in the XSD one data field could be transformed to a radio button group, a drop down box, or a plain and simple text input. Without for-each I couldn't walk through the two documents at the same time.
In general, I prefer matching templates. I find that it corresponds to the notion of a single transform applied at once better than for-each-ing this node, then the next, then the one after that, etc.. But that's a personal preference, of course.

Does LINQ to XML replace XSLT?

Is there anything you can do in XSLT that can't be done in LINQ to XML? Is it still important to learn XSLT? When would you choose one over the other?
Is there anything you can do in XSLT that can't be done in Linq to XML?
No, since LINQ to XML is an API used by Turing-complete programming languages, and covers more of XML Infoset than XSLT document model does (e.g. you can fully control the difference between text and CDATA nodes in L2X).
Is it still important to learn XSLT?
Depends on what you're doing. Broadly speaking, yes.
When would you choose one over the other?
XSLT is generally better when you need to do a transformation - i.e. both input and output is XML. There are a number of reasons for that. First of all, XSLT pattern matching is usually more concise than nested ?: in L2X queries, and far more readable. You can also use * to great effect to set up a default rule (like "copy everything", or "process children but do not generate output"), and then add rules for specific nodes you need to process in a special way - thus you do not need to write explicit loops/comprehensions for each node level in the document, as you often do in L2X. Finally, XPath is also more concise than L2X queries (at least in C#), so if you do a lot of non-trivial querying, it's likely to be far shorter and more readable in XSLT.
L2X is generally better when you need to quickly query a document for some value or node. The main advantage here is that there's less runtime overhead (XPath needs to be parsed, L2X query does not), and you don't need to mess with XmlNamespaceManager and other cruft - the API is streamlined for writing single-expression queries. As well, having nested from loops and let brings it closer to XQuery territory.
L2X is also the only choice when you need an in-place update of the document, and may be better when you only need to replace a few values in the document, and in-place update is an option - since XSLT doesn't let you touch the input in any way.
It is definitely still important to learn XSLT. LINQ to XML is great, but it's use is limited to .NET Apps.
XSLT can be applied across languages and platforms...even browsers can take XML and apply an XSLT to generate an output.
Don't forget that some .NET Application API's (CMS systems for example) still require you to supply XSLT to transform internal XML into an output. Ignoring the technology all together would be, in my opinion, a real mistake.
Not for anyone not using .NET

Two concepts from XSLT in other languages: apply-templates and xpath

Background: Having given up on the practical daily use of XSLT as a part of my programming toolkit, I was wondering if there were any implementations in other languages of the (only) two things I miss about that tool:
the ability to traverse data structures using "path" style statments via xpath
the ability to traverse template transformations using apply-templates instead of via an iterative or "looping" approach.
According to Google there are a couple of efforts out there to add "xpath-style" support to Javascript, but these have not apparently caught on very much. So far I haven't found anything where someone uses an "apply-templates" approach in another language
Question: Does anyone out there know of a programming language (hopefully one that is main-stream) that steals these two good ideas from XSLT, or applies the same or similar concepts using a different method?
the ability to traverse data structures using "path" style statments via xpath
I'm not aware of any other language that embeds XPath, but LINQ to XML is somewhat similar, particularly in its VB syntactic sugar incarnation. You could implement it in Common Lisp macros, or D templates, however.
the ability to traverse template transformations using apply-templates instead of via an iterative or "looping" approach.
No mainstream languages that I know of. Indeed, this feature is probably the main reason to use XSLT (and not e.g. XQuery, looking at closely related languages).
It's effectively extensible dynamic dispatch on receiver on arbitrary conditions - as such, I think you could probably do it in Common Lisp (CLOS, to be specific) - if I remember correctly, its multimethods can match arbitrary conditions, so if you have an XPath pattern evaluator, you could use it to emulate apply-templates, and even more - since apply-templates only dispatches on a single argument, while CLOS multimethods dispatch on multiple arguments.
XPath, while essential to making XSLT work, is independent of it; libraries like libxml give you it for free. The style of template application you describe is a little trickier; that's what you would normally use XSLT for.
Any programming language that does this should be functional. You could try writing your own, less-verbose, XSLT dialect; Perl also may give you enough rope to emulate this feature convincingly (although the performance implications are unclear).
The tough answer, though, is that this doesn't really exist, except as libraries for already existing languages.
For XPath, definitely. For C, there's Xalan-C++, for Java javax.xml.xpath (with multiple implementations), and C# has XPathNavigator and SelectNodes. If you want to use XPath for object hierarchies, look at JXPath.
For the template transformations, you should look at C#'s LINQ if you haven't already. It's not exactly the same thing, but it allows processing objects without explicit looping.
I have found nothing like that. But why would anybody use anything else to transform XML ? XSLT does a perfect job once you understand the non procedural way of developing solutions. Our applications are largely XSLT based and it is a really powerful tool.
A comment on your first requirement:
the ability to traverse data structures using "path" style statments via xpath
XPath makes a lot of assumptions on the data structure. If you're going to use it, you might as well convert your structure to XML because it's going to look like it anyway once you make it traversable via some XPath-like language unless you severely limit your XPath subset.
Also, keep in mind that the "only two things" that you are missing, XPath and template processing, are in-fact a huge part of what makes up Xslt. I'm curious why you decided to take it off of your tool-belt.
In spite of that fact that you wanted an Xslt alternative, I would still recommend Xslt and Xslt 2.0 in particular. With the addition of the unparsed-text and analyze-string you have a powerful text processing language. For example take a look at a CSV to XML stylesheet. Even though JSON isn't regular, you'd still be able to write a simple JSON to XML translator using recursive templates and transform the result at will.

when xsl:foreach is really useful?

Could anybody give an example when xsl:foreach is really useful?
I just made a project and concluded that everywhere I could replace it with appropriate <xsl:apply-templates />. <xsl:if> and <xsl:when/> sometimes make code shorter and i cannot effectively replace it with <apply-templates/> in functional style.
Is <xsl:foreach> considered harmful anyway?
Well, thanks everybody, i really couldn't choose the answer among the best. i think it would be better to collect different cases.
Sorry for somebody downvoting answers - it's not me:)
It's generally a matter of code style. If you're doing a for-each which is rather short, and needs to access variables from the parent block, it may be clearer to do a for-each there, rather than applying templates and passing in as parameters anything more that it needs.
There are definitely times that using templates is clearer, and definitely times that using for-each is clearer. They're both useful tools.
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.
I also think that it's a matter of style.
I have seen projects where XSLT stylesheets hardly used any <xsl:apply-templates> at all. They always used <xsl:call-template> instead. This is not so much a functional, but rather a procedural coding. And this approach inevitably leads you to exessive use of <xsl:for-each>.
Personally, I'll always prefer the style you suggested in your question. But it's a question of team management, skill and consistency that'll let you prefer one style or another.
I use for-each quite often because I have to build variables which are sub-sets of larger xml files.
<xsl:variable name="foo">
<xsl:for-each select="document('bar.xml')/item">
<xsl:if test="baz = bax">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
Is that possible with a template?
It may be that I'm one of those programmers who can't see the native XSL way to do things...