XSLT - 按顺序应用两个不同的模板

时间:2016-07-08 12:55:03

标签: xml xslt xpath

我有一个这样的XML文档:

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

我想应用两种不同的转换:

  • 从“hello world”到“hello guys”(使用替换功能)
  • 从“hello guys”到“HELLO GUYS”(使用翻译功能)

出于这个原因,我的XSLT样式表是这样的:

    

<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>

输出结果为:

<parent>
    <child>HELLO WORLD</child>
</parent>

你可以注意到我得到了HELLO WORLD而不是HELLO GUYS ......我认为我可以解决这个问题,在translate函数中创建替换函数。不幸的是,我需要将这两个操作分开(因此我使用了两个不同的模板元素)。我怎么能做到这一点?

2 个答案:

答案 0 :(得分:3)

您只能有一个模板与text()节点匹配 但您可以使用命名模板 尝试:

<!-- 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>

答案 1 :(得分:2)

如果您使用

模式
<!-- 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>

然后你可以使用两个模板来处理另一个模板的结果。