differences between for-each and templates in xsl?

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

Leave a Comment