XSLT: call-template vs mode for execution flow
Which is better practice to use for execution flow, call-template or modes?
data.xml
<Properties>
<foo>me</foo>
<bar>you</bar>
</Properties>
a.xsl
<xsl:include href="translations_nomodes.xml"
<xsl:template match="/">
<xsl:call-template name="a_display"/>
</xsl:template>
b.xsl
<xsl:include href="translations_nomodes.xml"
<xsl:template match="/">
<xsl:call-template name="b_display"/>
</xsl:template>
translations_nomodes.xsl
<xsl:templat开发者_开发知识库e name="a_display">
<!-- display option a -->
...
</xsl:template>
<xsl:template name="b_display">
<!-- display option b -->
...
</xsl:template>
Or would using modes be a better practice
c.xsl
<xsl:include href="translations_modes.xml"
<xsl:template match="/">
<xsl:apply-templates select="/Properties" mode="c_display"/>
</xsl:template>
d.xsl
<xsl:include href="translations_modes.xml"
<xsl:template match="/">
<xsl:apply-templates select="/Properties" mode="d_display"/>
</xsl:template>
translations_modes.xsl
<xsl:template match="Properties" mode="c_display">
<!-- display option c -->
...
</xsl:template>
<xsl:template match="Properties" mode="d_display">
<!-- display option d -->
...
</xsl:template>
Since "Properties" is the root node in my document and the apply-templates use literals for their mode values, using mode won't give me any added benefit and it's slightly more verbose. However if the execution flow is dependent upon an element/attribute within the document itself and the modes were not literals but expressions, then I could see the need for the mode approach.
In fact, using modes as I am, with literal values, seems like a bad choice also because if down the road my logic changes and I need to use mode expressions to control execution flow, I've already 'used' the mode attribute.
Have I come to the correct conclusion or am I missing some important points?
Little late for an answer to this. One big difference between apply-templates and call-template is that in the later case, the called template inherits the current node (sometimes called the context node) of the caller. Whereas with apply-template the select="expr" determines the context mode by generating a list of nodes and then iterating over them.
Using your examples, a.xsl and b.xsl both match "/". When they call-template a_display and b_display in translations_nomodes.xsl, those templates inherit "/" as the context node.
In contrast, the templates in c.xsl and d.xsl apply-templates with select="/Properties". Since there's only one "/Properties", it's the only node in the list to iterate over, and it becomes the context node that the XSLT processor looks for the best match for. Thus, the templates in translations_modes.xsl will see "/Properties" as the context node.
So which is the better practice? Depends on whether you want to continue processing with the current context node or select other nodes to start processing over.
Hope that helps.
Remember: XSLT (as any declarative language) binds an input with wellknown schema to an output with wellknown schema.
There is no such thing as "general solution".
Looking your example, this are the facts:
- Your input source has a
Properties
root element. - Your process logic doesn't rest in XSLT, but in your decision: to run one transformation or another.
So, why did you have a common stylesheet with separate logic, and two "entry point" stylesheets for each logic? This doesn't make sense.
Best practice would be to have two stylesheet.
精彩评论