简体   繁体   中英

XSLT - Apply two different template in sequence

I have an XML document like this:

<parent>
    <child>hello world</child>
</parent>

I want to apply two different transformations:

  • From "hello world" to "hello guys" (using the replace function)
  • From "hello guys" to "HELLO GUYS" (using the translation funciont)

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?

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>

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM