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.
相关问题
- XML - XSLT - document() function inside count() fu
- Google Test - generate values for template class i
- Template Specialization for Private Types
- zero length variadic expansion of ill-formed call
- Move product meta to the description tab in WooCom
相关文章
- How to use doMC under Windows or alternative paral
- Getting foreach() and ggplot2 to get along
- C++ Template specialization to provide extra membe
- SwiftUI automatically scroll to bottom in ScrollVi
- xslt localization
- C++: How to use unnamed template parameters in cla
- Templates, Function Pointers and C++0x
- foreach changes in PHP7
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 thanxsl:call-template
: you "throw" the selected nodes to the pattern matching mechanism, a truly "dynamic function invocation".I think this has some what to do with understanding push vs. pull style processing than just comparing
xsl:for-each
orxsl:template match="..."
. You often see programmers from another discipline using a lot ofxsl: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 withxsl: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 mostxsl:for-each
with anxsl:apply-templates
instead.Some benefits as I see it of using matching templates over a for-loop are:
xsl:next-match
in XSLT 2.0 you can chain templates together in powerful ways.xsl:apply-templates
and let the processor work for you.for-each
can only be used inside one place in your template. Templates can be re-used with differentapply-templates
calls. I mostly use templates instead of for-each because of the added flexibility.Here are some of the most important differences:
xsl:apply-templates
is much richer and deeper thanxsl: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 template
s 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:
<xsl:for-each>
.Reference and read more at: http://www.jenitennison.com/blog/node/9
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 heavilyxsl:apply-templates
... Especiallyxsl:apply-templates
with an implicit select (or a very generic select likeselect="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).