XSL递归地忽略空子

时间:2009-12-15 20:34:24

标签: xslt

在清理一些冗长的XML时尝试一些古怪的东西,即以递归方式删除所有空节点。

为此,如果节点具有(a)无子节点,(b)仅空白内容,(c)仅“空”子节点,则认为节点为“空”。也就是说,我认为以下内容为“空”,因为所有叶子都是空的/只有空白的节点:

<foo>
  <bar>
    <baz/>
  </bar>
  <quux>  </quux>
</foo>

我尝试在我的模板中使用<xsl:if test="child::node()">,但这似乎不起作用。完全可能的答案是“自己走树,傻”,但看起来XSL应该能够做到这一点?

我希望

<foo>
  <bar>
    <baz/>
  </bar>
  <quux>  </quux>
  <quuux>Actual content</quuux>
</foo>

回来
<foo>
  <quuux>Actual content</quuux>
</foo>

我想到了这个过滤器。

2 个答案:

答案 0 :(得分:5)

child::node()不适合你的原因是因为你确实有子节点 - 它们是空白文本节点。相反,尝试normalize-space() != ''之类的东西。您可能不希望if出现在match而是:

<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="*[normalize-space() = '']"/>

答案 1 :(得分:4)

帕维尔的回答是正确的。但是有两个小错误:您需要关闭xsl:copy节点,apply:templates使用select代替match。这将是最终版本:

<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="*[normalize-space() = '']"/>