模板匹配在XSLT 1.0上工作,但在XSLT 2.0中没有

时间:2013-12-17 13:30:20

标签: xslt xslt-1.0 xslt-2.0

我使用的是来自jre1.6的内置处理器的XSLT1.0 当我使用SAXONHE jar将处理器更改为XSLT2.0时,大多数模板匹配都无法正常工作。

<xsl:template match="@*|node()" name="identity">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="@source[. = 'SG']">
    <xsl:attribute name="source">MIG</xsl:attribute>  
</xsl:template>

<xsl:template match="customer/@homeAddress"/>

<xsl:param name="removeInvAttr" select="'indexDefinition|services|paymentMethod'"/>
<xsl:template match="invoice/@*">
    <xsl:for-each select="@*">
        <xsl:if test="not(name() = $removeInvAttr)">
            <xsl:call-template name="identity"/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:variable name="vLowercaseChars_CONST" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vUppercaseChars_CONST" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:template match="@country">
     <xsl:attribute name="country"><xsl:value-of select="translate(. , $vLowercaseChars_CONST , $vUppercaseChars_CONST)"/></xsl:attribute>
</xsl:template>

<xsl:template match="@claimingSystem">
    <xsl:if test="string-length(.) > 5">
        <xsl:attribute name="claimingSystem"><xsl:value-of select="substring(.,1,5)"/></xsl:attribute>
    </xsl:if>
</xsl:template>

以上所有模板除第一个模板“身份”外无效 如何使它们在XSLT 2.0和1.0中都有效?

输入xml是:

<dynamicData source="SG">
    <customer name="Cyrus S" homeAddress="NY" custType="P" country="us">
    <invoice amount="250" invType="C" indexDefinition="SECR" services="TYRE_REP" paymentMethod="CC" claimingSystem="EX001-S1"/>
    </customer>
</dynamicData>

预期输出为:

<dynamicData source="MIG">
    <customer name="Cyrus S" custType="P" country="US">
    <invoice amount="250" invType="C" claimingSystem="EX001"/>
    </customer>
</dynamicData>

这适用于XSLT 1.0。

1 个答案:

答案 0 :(得分:0)

我不知道如何

<xsl:param name="removeInvAttr" select="'indexDefinition|services|paymentMethod'"/>
<xsl:template match="invoice/@*">
    <xsl:for-each select="@*">
        <xsl:if test="not(name() = $removeInvAttr)">
            <xsl:call-template name="identity"/>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

可以执行任何操作,因为参数是一个字符串,其中多个名称由条|分隔,而且match="invoice/@*"一样重要,xsl:for-each select="@*"将不会选择任何内容(作为属性节点)因为上下文节点本身没有任何属性节点。)

所以我怀疑你想要

<xsl:param name="removeInvAttr" select="'indexDefinition|services|paymentMethod'"/>
<xsl:variable name="removeAttrNames" select="tokenize($removeInvAttr)"/>

<xsl:template match="invoice/@*[name() = $removeAttrNames]"/>