2009-12-15 51 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() = '']"/>