我正在尝试将 XML 文档转换为具有新根元素的文档,但该文档共享许多其他公共元素名称空间。我在命名空间转换方面遇到麻烦。
这是输入 XML:
<CreditNote
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2">
<cbc:CustomizationID>12345</cbc:CustomizationID>
<cbc:ProfileID>67890</cbc:ProfileID>
<cbc:ID>abcdef</cbc:ID>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>ghijk</cbc:ID>
<cbc:IssueDate>2024-08-05</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
</CreditNote>
这是我想要的输出 XML:
<?xml version="1.0" encoding="UTF-8"?>
<ubl: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"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:ID>abcdef</cbc:ID>
<cac:BillingReference>
<cac:InvoiceDocumentReference>
<cbc:ID>ghijk</cbc:ID>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
</ubl:Invoice>
根节点(或命名空间)旨在从“urn:oasis:names:specation:ubl:schema:xsd:CreditNote-2”切换到“urn:oasis:names:specation:ubl:schema:xsd:Invoice-” 2”,同时共享公共命名空间:
cac
和 cbc
。
我正在使用 XSLT 3.0 和 SAXON-HE 12.4。这是我的 XLST。我从这篇文章中得到了一些提示:XSLT 重命名合格的根元素,保留其他名称空间
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cn="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
exclude-result-prefixes="cn">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/cn:CreditNote">
<ubl:Invoice
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<xsl:apply-templates select="cbc:ID"/>
<xsl:apply-templates select="cac:BillingReference"/>
</ubl:Invoice>
</xsl:template>
<!--
Identity template, provides default behavior that copies all content into
the output Do not copy namespace attributes into elements.
-->
<xsl:template match="@* | node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!--
Copy all elements from the CreditNote namespace, but change the namespace
to the default namespace (Invoice).
-->
<xsl:template match="cn:*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="*/cac:BillingReference">
<xsl:copy>
<xsl:copy-of select="namespace::*[not(. = ('urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2'))]"/>
<xsl:apply-templates select="cac:InvoiceDocumentReference"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是我得到的输出 XML:
<?xml version="1.0" encoding="UTF-8"?>
<ubl: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"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:ID>abcdef</cbc:ID>
<cac:BillingReference xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2">
<cac:InvoiceDocumentReference>
<cbc:ID>ghijk</cbc:ID>
<cbc:IssueDate>2024-08-05</cbc:IssueDate>
</cac:InvoiceDocumentReference>
</cac:BillingReference>
</ubl:Invoice>
我知道 XSLT 正在尝试保留源命名空间,但我不清楚为什么我的 XSLT 没有解决这个问题。
xmlns="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
?cac:BillingReference
模板未匹配? (应该已经修剪过cbc:IssueDate
。)我认为以下就足够了:
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cn="urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
exclude-result-prefixes="cn">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/cn:CreditNote">
<ubl:Invoice
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<xsl:apply-templates select="cbc:ID"/>
<xsl:apply-templates select="cac:BillingReference"/>
</ubl:Invoice>
</xsl:template>
<!--
Identity template, provides default behavior that copies all content into
the output Do not copy namespace attributes into elements.
-->
<xsl:template match="@* | node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="cbc:IssueDate"/>
</xsl:stylesheet>