【发布时间】:2018-04-04 06:47:30
【问题描述】:
我正在使用XSLT 1.0(因为处理软件不支持 2.0)并且我一直在寻找一种方法来使我的输出 xml 上的所有命名空间定义为放在根节点。任何人都知道如何做到这一点?
下面是一个小例子,说明我在做什么、我得到了什么以及我追求什么:
输入 XML:
<document Version="1.4">
<Series>A</Series>
<Folio>321</Folio>
<Date>2017-05-05T01:00:00</Date>
<Complement>
<Other>
<Version>4.2</Version>
<Type>K</Type>
<PaymentDate>2016-12-13</PaymentDate>
</Other>
</Complement>
</document>
我的 XSLT:
<xsl:stylesheet extension-element-prefixes="xsi" version="1.0" xmlns:A="http://example.com/A" xmlns:C="http://example.com/C" xmlns:local="urn:local" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:B="http://example.com/B" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsi:schemaLocation="http://example.com/A http://example.com/A/A.xsd">
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0" omit-xml-declaration="yes"/>
<xsl:template match="/">
<xsl:element name="A:Document">
<xsl:attribute name="Version">
<xsl:text>9.1</xsl:text>
</xsl:attribute>
<xsl:if test="/document/Series/node() and /document/Series != ''">
<xsl:attribute name="Series">
<xsl:value-of select="/document/Series"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="/document/Folio/node() and /document/Folio != ''">
<xsl:attribute name="Folio">
<xsl:value-of select="/document/Folio"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="Date">
<xsl:value-of select="/document/Date"/>
</xsl:attribute>
<xsl:if test="/document/Complement/Other/node() or /document/Complement/Another/node()">
<xsl:element name="A:Complement">
<xsl:if test="/document/Complement/Other/node()">
<xsl:element name="B:Payment">
<xsl:call-template name="B:Payment">
<xsl:with-param name="Node" select="/document/Complement/Other"/>
</xsl:call-template>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:template>
<!--- COMPLEMENT-->
<xsl:template name="B:Payment">
<xsl:param name="Node"/>
<xsl:attribute name="Version">
<xsl:value-of select="$Node/Version"/>
</xsl:attribute>
<xsl:attribute name="Type">
<xsl:value-of select="$Node/Type"/>
</xsl:attribute>
<xsl:attribute name="PaymentDate">
<xsl:value-of select="$Node/PaymentDate"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
输出:
<A:Document Version="9.1" Series="A" Folio="321" Date="2017-05-05T01:00:00" xmlns:A="http://example.com/A">
<A:Complement>
<B:Payment Version="4.2" Type="K" PaymentDate="2016-12-13" xmlns:B="http://example.com/B" />
</A:Complement>
</A:Document>
我需要什么:
<A:Document Version="9.1" Series="A" Folio="321" Date="2017-05-05T01:00:00" xmlns:A="http://example.com/A" xmlns:B="http://example.com/B">
<A:Complement>
<B:Payment Version="4.2" Type="K" PaymentDate="2016-12-13" />
</A:Complement>
</A:Document>
如您所见,我需要将两个命名空间声明都保存在根节点(根据将处理此 XML 的软件的要求)
一些附加信息:
- 我只能使用前面提到的 XSLT 1.0,因为这是我目前可以使用的唯一工具支持的版本(有计划对此进行更改,但不会在不久的将来完成)
- 这必须完全使用 XSLT 完成
- 正如您可能从示例中推断的那样,“Other”节点是可选的,因此它可以存在(在这种情况下,输出中的命名空间是必需的)或不存在(在这种情况下,命名空间声明不应该是目前)
- 还有更多这种“可选”节点,每个节点都有自己的命名空间
- 但不一定只有 1 个 XSLT,如果可以通过将输出传递给新的 XSLT 来解决这个问题,那就可以了
我是一个 XSLT 新手,所以任何对此的帮助(或一些我可以学习如何做到这一点的文献的指导)将不胜感激
【问题讨论】:
-
感谢编辑=D
标签: xml xslt namespaces xslt-1.0