2009-12-15 72 views
2

在清理一些详细的XML时尝试某种古怪的方法,即以递归方式删除所有空节点。为此,如果节点具有(a)没有子节点,(b)只有空白的内容,(c)只有“空”子节点,我认为该节点是“空的”。也就是说,是“空”,因为所有的叶子都空/空白,只有节点I考虑以下几点:XSL忽略空子女递归

<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> 

此过滤器我的想法。

回答

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() = '']"/> 
+0

+1。 P.S .:见@ santiiiii的回答,他有效地指出了你的一些小毛病。 – Tomalak 2009-12-16 10:11:19

+0

已相应更正。 – 2009-12-16 17:15:23

+0

谢谢。这与santiiii的更正是我想要的。 – UltraNurd 2009-12-17 20:47:06

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() = '']"/>