非常感谢您的建议和答案。
下面是我的源代码
<?xml version="1.0" encoding="UTF-8"?>
<PurchaseOrderDocument creationDate="2017-09-26T18:37:48.837Z"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:dssuid="urn:autoid:specification:universal:Identifier:xml:schema:1"
xmlns:dsscore="urn:autoid:specification:interchange:PMLCore:xml:schema:1">
<PurchaseQuery>
<EventDate>20170926</EventDate>
<bizLocation>
<id>urn:ddd:id:sgln:0315563.00000.0</id>
</bizLocation>
<Serialization>
<BATCH_ID>3091145AB</BATCH_ID>
<EXPIRATION_DATE>20190504</EXPIRATION_DATE>
<PRODUCTION_DATE>20170505</PRODUCTION_DATE>
<GTIN>04028691544401</GTIN>
<Count>8088</Count>
</Serialization>
</PurchaseQuery>
</PurchaseOrderDocument>
此源xml具有不需要的命名空间 我的实际目标应如下所示
<?xml version="1.0" encoding="UTF-8"?>
<ns0:PurchaseOrderDocument xmlns:ns0="urn:global:mns:PurchaseOrder"
creationDate="2017-09-26T18:37:48.837Z">
<PurchaseQuery>
<EventDate>20170926</EventDate>
<bizLocation>
<id>urn:ddd:id:sgln:0315563.00000.0</id>
</bizLocation>
<Serialization>
<BATCH_ID>3091145AB</BATCH_ID>
<EXPIRATION_DATE>20190504</EXPIRATION_DATE>
<PRODUCTION_DATE>20170505</PRODUCTION_DATE>
<GTIN>04028691544401</GTIN>
<Count>8088</Count>
</Serialization>
</PurchaseQuery>
</ns0:PurchaseOrderDocument>
我尝试应用下面的XSLT,但属性不是目标所期望的顺序
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="2.0" encoding="UTF-8" />
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*" priority="1">
<xsl:element name="{local-name()}" >
<xsl:namespace name="ns0"
select="'urn:global:mns:PurchaseOrder'"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用XSLT后的输出如下
<?xml version='1.0' encoding='UTF-8' ?>
<PurchaseOrderDocument xmlns:ns0="urn:global:mns:PurchaseOrder"
creationDate="2017-09-26T18:37:48.837Z">
<PurchaseQuery>
<EventDate>20170926</EventDate>
<bizLocation>
<id>urn:ddd:id:sgln:0315563.00000.0</id>
</bizLocation>
<Serialization>
<BATCH_ID>3091145AB</BATCH_ID>
<EXPIRATION_DATE>20190504</EXPIRATION_DATE>
<PRODUCTION_DATE>20170505</PRODUCTION_DATE>
<GTIN>04028691544401</GTIN>
<Count>8088</Count>
</Serialization>
</PurchaseQuery>
</PurchaseOrderDocument>
我尝试了许多方法在命名空间之前获取属性创建日期但是徒劳无功。我无法理解我在哪里丢失。我见过很多博客但不幸的是我无法找到如何保留属性(这是动态值)在根节点中进入正确的位置,就像在目标结构中一样。这个逻辑对我来说有点重要。请建议我应该在XSLT代码中包含什么以获得实际的目标结构。任何帮助都将是非常感谢。
答案 0 :(得分:1)
序列化XML中的属性顺序(为此目的,名称空间声明计为属性)被认为没有意义,并且无法使用XSLT进行控制。我所知道的大多数其他序列化库也是如此。
Saxon确实有一个扩展名(xsl:output / @ saxon:attribute-order)来控制非命名空间属性的顺序,但它不会影响命名空间声明相对于属性的显示位置。
我不得不问为什么这么重要。如果您使用一致的解析器读取XML,那么它将不关心属性出现的顺序,如果您在不使用一致的解析器的情况下读取XML,那么您就犯了一个错误。
And also please help me how I can add prefix ns0: for each target line.
那是另一回事。但你不应该想“如何添加前缀”,你应该考虑“如何将输出元素放入命名空间urn:global:mns:PurchaseOrder
”。好吧,有三种创建输出元素的方法:
xsl:copy
将始终创建一个与原始名称相同的元素(名称空间URI加本地名称),因此不适合此处。
文字结果元素创建一个与样式表中的指令具有相同名称的元素(名称空间URI加本地名称)
xsl:element
有两个属性,名称和命名空间,允许您控制输出元素名称的两个部分。