Quote:
quote:Originally posted by mhkay
Unfortunately XSLT 1.0 has a (crazy) restriction that you can't apply-templates to a "result tree fragment".
|
Does it really? What exactly are the restrictions on it?
The reason I ask is because I found a stylesheet yesterday that does precisely that. I made a small example to test it:
xml:
Code:
<parent>
<child>
<children>kid A</children>
<children>kid B</children>
<children>kid C</children>
<children>kid D</children>
</child>
<child>
<kid>brats</kid>
<kid>brats</kid>
<kid>brats</kid>
</child>
</parent>
xslt:
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>
<xsl:template match="/">
<xsl:apply-templates/>
<xsl:text>#xA;#xA;</xsl:text>
<xsl:apply-templates>
<xsl:with-param name="rtf-test" select="parent/child/children"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="parent">
<xsl:param name="rtf-test" select="child/*"/>
<xsl:apply-templates select="$rtf-test" mode="rtf"/>
</xsl:template>
<xsl:template match="children" mode="rtf">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">, </xsl:if>
</xsl:template>
</xsl:stylesheet>
output:
Code:
kid A, kid B, kid C, kid D, bratsbratsbrats
kid A, kid B, kid C, kid D
Needless to say, this intrigued me. A
lot. (Some of us aren't fortunate enough to have access to an XSLT 2.0 processor at work yet. T_T) But this works in all the 1.0 processors I've tried, and I can't find more explicit information about it.
The original stylesheet is only a few weeks old, but I suspect the concept has been around for a lot longer.
So... concerning result-tree-fragments vs. node-sets, I now assume the only differences are:
1) you can't apply xpath expressions when selecting what nodes to apply the templates to - it's a one-shot apply from the root node on downward
2) you have to make damn sure that your templates matching a root-node know exactly what they're doing, or otherwise it'll catch the variable's root. (i.e. always start with <xsl:template match="/document-root-node"> rather than <xsl:template match="/">, or always use a mode like so: <xsl:apply-templates select="$rtf-to-traverse" mode="rtf"/>)
In the basic example I've made, and even in the FizzBuzz example, it's not really worth arguing, seeing that one could simply use a key to achieve the same thing. However, when you can continue and apply this to variables consisting of complex node-sets, nested parameter calls, and so on with the freedom of XSLT 2.0 (only a lot more controlled and RTF-aware) - it sounds like it could open up a lot of doors for those of us still confined to XSLT 1.0.
Anything I'm mistaken about here? I'd like to know of any shortcomings in my logic before I start relying on this functionality in the future.