使用XSLT删除XML的节点 - 不需要针对删除的节点/字段使用CRLF

时间:2014-05-14 11:34:51

标签: xslt

我正在使用以下XSLT从XML中删除空节点。它通过删除空节点工作正常,但它也添加了CRLF来代替已删除的节点。

<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="*[not(child::node())]"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

Extra CRLFs

我不需要这些CRLF。请提出建议!

3 个答案:

答案 0 :(得分:1)

可能就是这样。例如。

<root>
  <foo></foo>
  <foo>2</foo>
</root>

结果

<root>

  <foo>2</foo>
</root>

因为您的代码删除了元素,但没有删除任何前面或尾随的空格文本节点。

在很多情况下只是做

<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes"/>
<xsl:strip-space elements="*"/>

避免问题并为您提供良好且一致的缩进。

或者您需要编写模板,以确保在删除空元素之前或之后的空格文本节点。

答案 1 :(得分:1)

它不是添加任何内容,但它也不是删除原始XML中元素之间的空白文本节点。如果您的XML没有混合内容,那么最简单的方法是删除所有仅空白文本节点,然后重新缩进结果树:

<xsl:strip-space elements="*" />
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" />

如果您需要保留原始XML的缩进,那么您需要更具创意

<xsl:template match="*[not(child::node())]"/>
<xsl:template match="text()[not(normalize-space())]
               [preceding-sibling::node()[1][self::*][not(child::node())]]" />

第二个模板将压缩只有空格的文本节点,这些节点紧跟在第一个模板被压扁的元素之后。

答案 2 :(得分:0)

对我有用的其他解决方案是使用翻译。下面是XSLT:

<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
  <xsl:template match="*[not(child::node())]"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="text()">
    <xsl:value-of select="translate(., '&#10;&#13;', '')"/>
  </xsl:template>