Reputation: 689
I have an XML document like this:
<parent>
<child>hello world</child>
</parent>
I want to apply two different transformations:
For this reason, my XSLT stylesheet i something like this:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- First Transformation -->
<xsl:template match="text()" >
<xsl:value-of select="replace(. , 'world', 'guys')"/>
</xsl:template>
<!-- Second Transformation -->
<xsl:template match="text()">
<xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
</xsl:template>
The output is:
<parent>
<child>HELLO WORLD</child>
</parent>
You can notice that I get HELLO WORLD and not HELLO GUYS... I think that I can solve this problem making the replace function inside the translate function. Unfortunatelly I need to have this two operation well separated (for this reason I used two different template element). How can I achive this?
Upvotes: 2
Views: 3634
Reputation: 167696
If you use a mode with
<!-- First Transformation -->
<xsl:template match="text()">
<xsl:variable name="t1" as="text()">
<xsl:value-of select="replace(. , 'world', 'guys')"/>
</xsl:variable>
<xsl:apply-templates select="$t1" mode="mode1"/>
</xsl:template>
<!-- Second Transformation -->
<xsl:template match="text()" mode="mode1">
<xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
</xsl:template>
then you can use two templates where one processes the result of another.
Upvotes: 3
Reputation: 9627
You can only have one template match the text() nodes.
But you can use named templates
Try:
<!-- First Transformation -->
<xsl:template name="replace" >
<xsl:param name="text" select="." />
<xsl:value-of select="replace($text , 'world', 'guys')"/>
</xsl:template>
<!-- Second Transformation -->
<xsl:template name="translate">
<xsl:param name="text" select="." />
<xsl:value-of select="translate($text, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')" />
</xsl:template>
<xsl:template match="text()" >
<xsl:variable name="step1">
<xsl:call-template name="replace">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="translate">
<xsl:with-param name="text" select="$step1"/>
</xsl:call-template>
</xsl:template>
Upvotes: 3