如何使用 XSLT 2.0 或 XSLT 3.0 使用模板匹配替换值
How to replace values using templates match using XSLT 2.0 or 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>
使用第一个模板匹配的缺点是以下模板不会生效。如果我评论第一个模板,那么以下模板可以正常工作。我需要第一个模板的另一个原因是在这个 post.
中解释没有意义
输入:
<?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>
我应该怎么做才能获得所需的输出?
给我任何建议。
解决方案很简单:在第一个模板中更改行
<xsl:copy-of select="cac:TaxSubtotal"/>
至
<xsl:apply-templates select="cac:TaxSubtotal"/>
然后将应用所有后续模板,您的样式表将按需要工作。
之所以有效,是因为您在代码中使用
行定义了与 身份模板 等效的 XSLT-3.0
<xsl:mode on-no-match="shallow-copy" />
负责复制节点。
我想根据标签 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>
使用第一个模板匹配的缺点是以下模板不会生效。如果我评论第一个模板,那么以下模板可以正常工作。我需要第一个模板的另一个原因是在这个 post.
中解释没有意义输入:
<?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>
我应该怎么做才能获得所需的输出? 给我任何建议。
解决方案很简单:在第一个模板中更改行
<xsl:copy-of select="cac:TaxSubtotal"/>
至
<xsl:apply-templates select="cac:TaxSubtotal"/>
然后将应用所有后续模板,您的样式表将按需要工作。
之所以有效,是因为您在代码中使用
行定义了与 身份模板 等效的 XSLT-3.0<xsl:mode on-no-match="shallow-copy" />
负责复制节点。