如何为格式不正确的XML结构添加额外的根节点



我们有以下来自源系统的格式不正确的输入XML。

<?xml version="1.0" encoding="UTF-8"?>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="XYZ10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">703760000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY67" language="EN">package1</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">274.50</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">58.41</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">D19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="ABC10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">702390000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY34" language="EN">package2</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">76.25</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">9.74</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">Y19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>

如果我能将下面的标记添加到上面的输入中,我就可以使上面的xml格式良好。

开始标签:

<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>

对应的结束标记:

</ns0:Message1>
</ns0:Messages>

如何编写XSLT逻辑,以便生成以下输出?

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="XYZ10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">703760000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY67" language="EN">package1</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">274.50</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">58.41</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">D19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="ABC10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">702390000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY34" language="EN">package2</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">76.25</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">9.74</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">Y19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>
</ns0:Message1>
</ns0:Messages>

我尝试了很多方法,但由于输入不是格式良好的XML,所以在生成上述输出时遇到了问题。

您可以在Saxon 9.8或9.9或Altova 2017/2018/2019支持的XSLT3中使用XPath 3parse-xml-fragment函数来实现这一点,例如,您可以将片段作为字符串参数传入:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="fragment-string" as="xs:string"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="XYZ10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">703760000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY67" language="EN">package1</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">274.50</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="credit Amount">58.41</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">D19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>
<ns0:invoiceOrder xmlns:ns0="http://cts.com"
type="ABCD"
businessDivision="X0"
salesOrganization="ABC10"
Channel="Y0">
<ns0:references>
<ns0:key type="Source System">ABC</ns0:key>
<ns0:relationship scheme="Customer" schemeAgency="APAC" role="Sell to">702390000</ns0:relationship>
<ns0:document type="Purchase Order">AB123</ns0:document>
</ns0:references>
<ns0:notes>
<ns0:note type="XY34" language="EN">package2</ns0:note>
</ns0:notes>
<ns0:orderLines>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">100411</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">76.25</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
<ns0:orderLine>
<ns0:identifiers>
<ns0:identifier scheme="Item" schemeAgency="ABC">140072</ns0:identifier>
</ns0:identifiers>
<ns0:amounts>
<ns0:amount type="Rebate Amount">9.74</ns0:amount>
</ns0:amounts>
</ns0:orderLine>
</ns0:orderLines>
<ns0:terms>
<ns0:term type="Reason Code">Y19</ns0:term>
<ns0:term type="Payment Terms">Y000</ns0:term>
</ns0:terms>
<ns0:billingInfo>
<ns0:paymentMethod/>
</ns0:billingInfo>
<ns0:flags>
<ns0:flag type="1099 Payment Flag">Y</ns0:flag>
</ns0:flags>
<ns0:dates>
<ns0:date type="Proposed Invoice Date">2018-11-02</ns0:date>
</ns0:dates>
</ns0:invoiceOrder>]]></xsl:param>
<xsl:output indent="yes"/>
<xsl:template match="/" name="xsl:initial-template">
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>
<xsl:sequence select="parse-xml-fragment($fragment-string)"/>
</ns0:Message1>
</ns0:Messages>
</xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/bFDb2Dd

当然,在XSLT2/3中,您也可以使用unparsed-text加载带有片段的其他文档,例如

<xsl:param name="fragment-uri" as="xs:string">fragment.xml</xsl:param>
<xsl:param name="fragment-string" as="xs:string" select="unparsed-text($fragment-uri)"/>

示例位于https://xsltfiddle.liberty-development.net/bFDb2Dd/1.

在支持外部实体的XML级别上,您可以使用具有所需包装器元素的文档,其中包含作为外部实体的片段,例如http://xsltransform.hikmatu.com/jyH9rLR或https://xsltfiddle.liberty-development.net/eiZQaGf,您将声明包装文档为

<!DOCTYPE ns0:Messages [
<!ENTITY external-fragment SYSTEM "fragment.xml">
]>
<ns0:Messages xmlns:ns0="http://sap.com/xi/XI/SplitAndMerge">
<ns0:Message1>&external-fragment;</ns0:Message1>
</ns0:Messages>

最新更新