xml - 使用 XSLT 将 XML 输出转换为新结构化的(其他元素)XML 时,如何在 XML 根标记中包含元素
问题描述
从 CRM 系统中,我得到一个包含所有元素的预定义结构的 XML。我的客户希望将生成的 XML 导入他们的 ERP 中,但是需要对其进行重组以适应他们的系统。我能够使用 XSLT 按照他们的意愿对其进行转换。但是,我无法向元素添加属性(有关更多详细信息,请参见下面的代码)。有人知道我如何在我的 XSLT 中对其进行硬编码,以便在 XML 中获得我想要的输出吗?
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="com.cisag.app.sales.obj.SalesOrder"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:import-schema schema-location="SALESORDER.xsd"
namespace="com.cisag.app.sales.obj.SalesOrder"/>
<xsl:output method="xml" indent="yes" version="1.0" encoding="UTF-8"/>
<xsl:variable name="dateTime" select="//ActionDateTime"/>
<xsl:variable name="date" select="concat(substring($dateTime,9,2), '#',
substring($dateTime,6,2), '#', substring($dateTime,1,4))"/>
<xsl:template match="/">
<xsl:element name="semiramis">
<xsl:element name="SalesOrder">
<xsl:element name="Type">
<xsl:element name="code">
<xsl:value-of select="105"/>
</xsl:element>
</xsl:element>
<xsl:element name="invoicingPartyData">
<xsl:element name="Partner">
<xsl:element name="number">
<xsl:value-of select="0"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="customerOrderData">
<xsl:element name="purchaseOrder">
<xsl:value-of select="//WrntyID"/>
</xsl:element>
<xsl:element name="date">
<xsl:value-of select="$date"/>
</xsl:element>
</xsl:element>
<xsl:element name="imp_description">
<xsl:value-of select="//Remark"/>
</xsl:element>
<xsl:element name="customerData">
<xsl:element name="CustomerPartner">
<xsl:element name="number">
<xsl:value-of select="//AccountExternalID"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="discountOriginType">
<xsl:value-of select="('MANUAL')"/>
</xsl:element>
<xsl:element name="discounts">
<xsl:element name="type">
<xsl:value-of select="('PERCENT_VALUE')"/>
</xsl:element>
<xsl:element name="value">
<xsl:value-of select="//DiscountPercentage"/>
</xsl:element>
<xsl:element name="DiscountType">
<xsl:element name="code">
<xsl:value-of select="200"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:for-each select="//TransactionLine">
<xsl:element name="Details">
<xsl:element name="Item">
<xsl:element name="number">
<xsl:value-of select="//ItemExternalID"/>
</xsl:element>
</xsl:element>
<xsl:element name="totalQuantity">
<xsl:element name="amount">
<xsl:value-of select="//UnitsQuantity"/>
</xsl:element>
<xsl:element name="Uom">
<xsl:element name="code">
<xsl:value-of
select="//ItemTSABasiseinheit"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:element name="priceOriginType">
<xsl:value-of select="('MANUAL')"/>
</xsl:element>
<xsl:element name="grossPrice">
<xsl:element name="amount">
<xsl:value-of select="//TSAPreisvorRabatt"/>
</xsl:element>
<xsl:element name="Currency">
<xsl:element name="isoCode">
<xsl:value-of select="('EUR')"/>
</xsl:element>
</xsl:element>
</xsl:element>
<xsl:choose>
<xsl:when test="//TSAZeilenrabatt">
<xsl:element name="discounts">
<xsl:element name="type">
<xsl:value-of select="
('PERCENT_VALUE')"/>
</xsl:element>
<xsl:element name="value">
<xsl:value-of
select="//TSAZeilenrabatt"/>
</xsl:element>
<xsl:element name="DiscountType">
<xsl:element name="code">
<xsl:value-of select="200"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:when>
</xsl:choose>
<xsl:element name="imp_deliveryDate">
<xsl:element name="dateFrom">
<xsl:element name="specialValue">
<xsl:value-of select="('NONE')"/>
</xsl:element>
<xsl:element name="date">
<xsl:value-of select="//DeliveryDate"/>
</xsl:element>
<xsl:element name="timeZone">
<xsl:value-of select="('CET')"/>
</xsl:element>
</xsl:element>
<xsl:element name="dateUntil">
<xsl:element name="specialValue">
<xsl:value-of select="('NONE')"/>
</xsl:element>
<xsl:element name="date">
<xsl:value-of select="//TSALieferdatumBis"/>
</xsl:element>
<xsl:element name="timeZone">
<xsl:value-of select="('CET')"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
这是我期望收到的:
<?xml version="1.0" encoding="UTF-8"?>
<semiramis xmlns="com.cisag.app.sales.obj.SalesOrder"
xsi:schemaLocation="com.cisag.app.sales.obj.SalesOrder SALESORDER.xsd"
created="2014-04-16T14:03:28.256Z" locale="en-US-XMLSchemaCompliant"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
nlsMode="SINGLE_LANGUAGE" dateTimeMode="NORMALIZED">
<SalesOrder xmlns="com.cisag.app.sales.obj.SalesOrder">
<Type>
<code></code>
</Type>
<invoicingPartyData>
<Partner>
<number></number>
</Partner>
</invoicingPartyData>
<customerOrderData>
<purchaseOrder></purchaseOrder>
<date>08#01#2019</date>
</customerOrderData>
<imp_description></imp_description>
<customerData>
<CustomerPartner>
<number></number>
</CustomerPartner>
</customerData>
<discountOriginType>MANUAL</discountOriginType>
<discounts>
<type>PERCENT_VALUE</type>
<value>0</value>
<DiscountType>
<code>199</code>
</DiscountType>
</discounts>
<Details>
<Item>
<number>010</number>
</Item>
<totalQuantity>
<amount>900</amount>
<Uom>
<code></code>
</Uom>
</totalQuantity>
<priceOriginType>MANUAL</priceOriginType>
<grossPrice>
<amount></amount>
<Currency>
<isoCode>EUR</isoCode>
</Currency>
</grossPrice>
<discounts>
<type>PERCENT_VALUE</type>
<value>13</value>
<DiscountType>
<code></code>
</DiscountType>
<MeasureUom />
<MeasureCurrency />
</discounts>
<imp_deliveryDate>
<dateFrom>
<specialValue>NONE</specialValue>
<date>2019-01-08</date>
<timeZone>CET</timeZone>
</dateFrom>
<dateUntil>
<specialValue>NONE</specialValue>
<date></date>
<timeZone>CET</timeZone>
</dateUntil>
</imp_deliveryDate>
</Details>
</SalesOrder>
</semiramis>
这是我实际得到的:
<?xml version="1.0" encoding="utf-8"?>
<semiramis xmlns="com.cisag.app.sales.obj.SalesOrder">
<SalesOrder>
<Type>
<code></code>
</Type>
<invoicingPartyData>
<Partner>
<number></number>
</Partner>
</invoicingPartyData>
<customerOrderData>
<purchaseOrder></purchaseOrder>
<date>08#01#2019</date>
</customerOrderData>
<imp_description></imp_description>
<customerData>
<CustomerPartner>
<number></number>
</CustomerPartner>
</customerData>
<discountOriginType>MANUAL</discountOriginType>
<discounts>
<type>PERCENT_VALUE</type>
<value>0</value>
<DiscountType>
<code>199</code>
</DiscountType>
</discounts>
<Details>
<Item>
<number>010</number>
</Item>
<totalQuantity>
<amount>900</amount>
<Uom>
<code></code>
</Uom>
</totalQuantity>
<priceOriginType>MANUAL</priceOriginType>
<grossPrice>
<amount></amount>
<Currency>
<isoCode>EUR</isoCode>
</Currency>
</grossPrice>
<discounts>
<type>PERCENT_VALUE</type>
<value>13</value>
<DiscountType>
<code></code>
</DiscountType>
<MeasureUom />
<MeasureCurrency />
</discounts>
<imp_deliveryDate>
<dateFrom>
<specialValue>NONE</specialValue>
<date>2019-01-08</date>
<timeZone>CET</timeZone>
</dateFrom>
<dateUntil>
<specialValue>NONE</specialValue>
<date></date>
<timeZone>CET</timeZone>
</dateUntil>
</imp_deliveryDate>
</Details>
</SalesOrder>
</semiramis>
解决方案
要将属性和命名空间声明添加到根semiramis
元素,请替换:
<xsl:element name="semiramis">
...
</xsl:element>
和:
<semiramis xmlns="com.cisag.app.sales.obj.SalesOrder"
xsi:schemaLocation="com.cisag.app.sales.obj.SalesOrder SALESORDER.xsd"
created="2014-04-16T14:03:28.256Z" locale="en-US-XMLSchemaCompliant"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
nlsMode="SINGLE_LANGUAGE" dateTimeMode="NORMALIZED">
...
</semiramis>"
如果其中一些属性需要动态评估其值,请使用属性值模板或显式xsl:attribute
指令 - 例如:
<semiramis xmlns="com.cisag.app.sales.obj.SalesOrder"
xsi:schemaLocation="com.cisag.app.sales.obj.SalesOrder SALESORDER.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
nlsMode="SINGLE_LANGUAGE" dateTimeMode="NORMALIZED">
<xsl:attribute name="created">
<xsl:value-of select="something-here"/>
</xsl:attribute>
<xsl:attribute name="locale">
<xsl:value-of select="another-thing-here"/>
</xsl:attribute>
...
注意:通常,最好使用文字结果元素而不是xsl:element
. IOW,替换以下内容:
<xsl:element name="Type">
<xsl:element name="code">
<xsl:value-of select="105"/>
</xsl:element>
</xsl:element>
和:
<Type>
<code>105</code>
</Type>
xsl:element
当元素的名称或命名空间需要在运行时动态确定时使用。
推荐阅读
- postgresql - 函数 crosstab(unknown, unknown) 不存在,但确实存在
- android - 将数据添加到实时数据库
- makefile - Makefile FILES 命令不会执行
- python - 如何使用 PySide2 Python 后端在 QML 中嵌入 PyQtGraph?
- php - 如何在 Heroku 免费计划上部署 laravel-websockets 服务器?
- angular - 为什么不调用我的 Angular 前端和 springboot 后端
- android - this.getPreferences() 上的 NullPointerException
- php - 在 Web 应用程序上下文中使用 mysql INTO OUTFILE
- amazon-web-services - AWS Lightsail 终端受阻
- bluetooth - 低功耗蓝牙配对与非配对通信