如何使用XSLT调整XML中Invoice元素的子元素顺序
正确调整XML子元素顺序的XSLT方案
你的需求是把cec:UBLExtensions移到Invoice的首位,其余元素保留原有顺序,但现有XSLT存在两个核心问题:
- 未声明XML中用到的命名空间(
cbc、cec、cac前缀对应的命名空间),导致XSLT无法识别这些元素 - 子元素选择逻辑混乱,遗漏了
cbc:Note,还错误拆分了元素输出顺序
修正后的XSLT代码
<?xml version="1.0" encoding="UTF-8" ?> <xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"> <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> <!-- 处理Invoice元素,调整子元素顺序 --> <xsl:template match="Invoice"> <xsl:copy> <!-- 先输出UBLExtensions --> <xsl:apply-templates select="cec:UBLExtensions"/> <!-- 输出剩余所有子元素,保持原有顺序(排除已经输出的UBLExtensions) --> <xsl:apply-templates select="* except cec:UBLExtensions"/> </xsl:copy> </xsl:template> <!-- 身份模板:复制所有其他节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:transform>
关键说明
- 命名空间声明:必须在XSLT根元素上添加XML中用到的所有命名空间前缀映射,否则XSLT无法匹配到带命名空间的元素(你的原始XML里的
cbc、cec、cac都是UBL标准的命名空间,上面的映射是标准值) - 顺序调整逻辑:
- 先单独输出
cec:UBLExtensions,确保它在首位 - 用
* except cec:UBLExtensions选择剩下的所有子元素,这样会自动保留这些元素原来的先后顺序(包括cbc:CustomizationID、cbc:ID、cbc:Note、cac:InvoicePeriod等)
- 先单独输出
- 身份模板:负责原样复制所有其他节点(包括子元素的内容、属性等),保证XML结构和内容的完整性
测试用原始XML(整理格式后)
<Invoice> <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:mfin.gov.rs:srbdt:2021</cbc:CustomizationID> <cbc:ID>701708-2022</cbc:ID> <cbc:IssueDate>2022-11-06</cbc:IssueDate> <cbc:DueDate>2022-11-21</cbc:DueDate> <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode> <cbc:Note>Nema oslobadjanja dobara od PDV-a</cbc:Note> <cbc:DocumentCurrencyCode>RSD</cbc:DocumentCurrencyCode> <cec:UBLExtensions> <cec:UBLExtension> <cec:ExtensionContent></cec:ExtensionContent> </cec:UBLExtension> </cec:UBLExtensions> <cac:InvoicePeriod> <cbc:DescriptionCode>35</cbc:DescriptionCode> </cac:InvoicePeriod> </Invoice>
执行修正后的XSLT后,cec:UBLExtensions会被移到Invoice的第一个子元素位置,其余元素保持原有顺序不变。
内容的提问来源于stack exchange,提问作者Dusko
相关产品推荐
相关产品推荐

