如何不在 XSLT 2.0 的输出中复制属性

How to not copy an attribute in the output of XSLT 2.0

我想将一个 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">&lt;?xml-multiple?&gt;</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>

当您执行 <xsl:copy-of select="node() except @nil" /> 时,您正在复制当前 row 的子元素,这将复制它们而不做任何更改。 except @nil 不会执行您期望的操作,因为它将在当前 row 元素上查找名为 @nil 的属性(而您要查找的属性无论如何都是 @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 来创建处理指令)。