如何使用模板匹配替换值(使用XSLT 2.0或XSLT 3.0)

时间:2019-01-23 21:44:22

标签: xml xslt-2.0 xslt-3.0

我想根据标签cbc:TaxExemptionReasonCode的值更改XML的输入值,如果此类标签的值类似于11,12,13,14,15,16,21,31,32,33,34 ,35,36,37,则必须将标记cac:TaxScheme内的值更改为另一个值,如我将在下面显示的那样。

我尝试使用XSLT 3.0进行模板匹配(也可能是XSLT 2.0) 我的代码:

<xsl:mode on-no-match="shallow-copy" />
<xsl:template match="cac:TaxTotal">
    <xsl:variable name="taxTotal" select="../cac:TaxTotal"/>
    <xsl:copy>
        <xsl:copy-of select="$taxTotal[cac:TaxSubtotal/cac:TaxCategory/cac:TaxScheme/cbc:ID[text()='1000']]/cbc:TaxAmount"/>
        <xsl:for-each select="$taxTotal">
            <xsl:copy-of select="cac:TaxSubtotal"/>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>
<xsl:template match="cac:TaxScheme[../cbc:TaxExemptionReasonCode[matches(text(), '^(11|12|13|14|15|16|21|31|32|33|34|35|36|37)$')]]">
    <xsl:copy>
        <cbc:ID>9996</cbc:ID>
        <cbc:Name>GRA</cbc:Name>
        <cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>
    </xsl:copy>
</xsl:template>

使用第一个模板匹配项的缺点是以下模板没有生效。如果我评论第一个模板,则以下模板可以正常工作。我需要第一个模板是出于另一个原因,即在这篇文章中没有解释的必要。

输入:

    <?xml version="1.0" encoding="utf-8" standalone="no"?>
<Invoice
    xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
    <cac:TaxTotal>
        <cbc:TaxAmount currencyID="PEN">198.00</cbc:TaxAmount>
        <cac:TaxSubtotal>
            <cbc:TaxAmount currencyID="PEN">198.00</cbc:TaxAmount>
            <cbc:Percent>18.00</cbc:Percent>
            <cac:TaxCategory>
                <cbc:TaxExemptionReasonCode>12</cbc:TaxExemptionReasonCode>
                <cac:TaxScheme>
                    <cbc:ID>1000</cbc:ID>
                    <cbc:Name>IGV</cbc:Name>
                    <cbc:TaxTypeCode>VAT</cbc:TaxTypeCode>
                </cac:TaxScheme>
            </cac:TaxCategory>
        </cac:TaxSubtotal>
    </cac:TaxTotal>
</Invoice>

所需的输出:

    <Invoice
    xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
    <cac:TaxTotal>
        <cbc:TaxAmount currencyID="PEN">198.00</cbc:TaxAmount>
        <cac:TaxSubtotal>
            <cbc:TaxAmount currencyID="PEN">198.00</cbc:TaxAmount>
            <cbc:Percent>18.00</cbc:Percent>
            <cac:TaxCategory>
                <cbc:TaxExemptionReasonCode>12</cbc:TaxExemptionReasonCode>
                <cac:TaxScheme>
                    <cbc:ID>9996</cbc:ID>
                    <cbc:Name>GRA</cbc:Name>
                    <cbc:TaxTypeCode>FRE</cbc:TaxTypeCode>
                </cac:TaxScheme>
            </cac:TaxCategory>
        </cac:TaxSubtotal>
    </cac:TaxTotal>
</Invoice>

我应该怎么做才能获得所需的输出? 给我任何建议。

1 个答案:

答案 0 :(得分:2)

解决方案很简单:在第一个模板中更改行

<xsl:copy-of select="cac:TaxSubtotal"/>

<xsl:apply-templates select="cac:TaxSubtotal"/>

然后将应用所有后续模板,并且样式表将根据需要工作。

之所以行之有效,是因为您在代码中使用以下代码行定义了身份模板的XSLT-3.0版本

<xsl:mode on-no-match="shallow-copy" />

负责复制节点。