我想将一种XML消息转换为另一种。我的输入消息当前包含一些属性为@ nil = ture的空元素。我想要的是应该将这些元素创建为空,但没有nill属性。请在下面查看我目前的进展情况:
输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<collection>
<row>
<nr>A00</nr>
<type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</row>
<row>
<nr>A01</nr>
<type>mash</type>
</row>
</collection>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="//*[local-name()='collection']">
<jsonArray>
<xsl:text disable-output-escaping="yes"><?xml-multiple?></xsl:text>
<xsl:for-each select="//*[local-name()='row']">
<jsonObject>
<xsl:copy-of select="node() except @nil" />
</jsonObject>
</xsl:for-each>
</jsonArray>
</xsl:template>
</xsl:stylesheet>
当前输出:
<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
<?xml-multiple?>
<jsonObject>
<nr>A00</nr>
<type xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
</jsonObject>
<jsonObject>
<nr>A01</nr>
<type>mash</type>
</jsonObject>
</jsonArray>
预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<jsonArray>
<?xml-multiple?>
<jsonObject>
<nr>A00</nr>
<type/>
</jsonObject>
<jsonObject>
<nr>A01</nr>
<type>mash</type>
</jsonObject>
</jsonArray>
答案 0 :(得分:2)
当您执行<xsl:copy-of select="node() except @nil" />
时,您正在复制当前row
的子元素,这些子元素将被复制而无需更改。 except @nil
不会执行您期望的操作,因为它将在当前@nil
元素上寻找名为row
的属性(无论如何,您寻找的属性是@xsi:nil
相反,将xsl:copy-of
替换为xsl:apply-templates
,并将身份模板添加到您的XSLT(稍作调整即可删除名称空间声明)。
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
然后,您只需要一个模板即可忽略xsl:type
<xsl:template match="@xsi:nil" />
尝试使用此XSLT
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsi">
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@xsi:nil" />
<xsl:template match="//*[local-name()='collection']">
<jsonArray>
<xsl:processing-instruction name="xml-multiple" />
<xsl:for-each select="//*[local-name()='row']">
<jsonObject>
<xsl:apply-templates select="@*|node()" />
</jsonObject>
</xsl:for-each>
</jsonArray>
</xsl:template>
</xsl:stylesheet>
(请注意,您确实应该使用xsl:processing-instruction
来创建处理说明)。