2016-02-12 150 views
2

我試圖清理與看起來像任意元素名稱的文件:遞歸空節點清理

<root> 
    <nodeone> 
     <subnode>with stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode>with other stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode /> 
    </nodeone> 
</root> 

成看起來像一個文件:

<root> 
    <nodeone> 
     <subnode>with stuff</subnode> 
    </nodeone> 
    <nodeone> 
     <subnode>with other stuff</subnode> 
    </nodeone> 
</root> 

你可以看到所有有空子女的「nodeone」消失了。我使用的解決方案刪除了​​空的<subnode>,但保留<nodeone>。期望的結果是這兩個元素都被刪除。

我一個解決方案,當前的嘗試(它恰恰沒有)是:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml"/> 

    <xsl:template match="node()|@*"> 
     <xsl:call-template name="backwardsRecursion"> 
      <xsl:with-param name="elementlist" select="/*/node/*[normalize-space()]"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="backwardsRecursion"> 
     <xsl:param name="elementlist"/> 

     <xsl:if test="$elementlist"> 
      <xsl:apply-templates select="$elementlist[last()]"/> 

      <xsl:call-template name="backwardsRecursion"> 
       <xsl:with-param name="elementlist" select="$elementlist[position() &lt; last()]"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="/*/node/*[normalize-space()]"> 
      <xsl:value-of select="."/> 
    </xsl:template> 
</xsl:stylesheet> 

XSLT是不是我非常經常使用,所以我有點失落。

+1

這在我看來是一個很好問的問題。很顯然,您已經試圖找到一種遞歸調用模板的方式,就像您在其他編程語言中一樣。然而,XSLT的美妙之處在於,它默認遞歸地應用模板,並且您編寫的代碼通常會停止或更改遞歸過程 - 正如下面的kjhughes所示。 –

回答

2

開始與身份轉換,

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

,並添加一個模板來壓制不signficant,非空間標準化的字符串值的元素,

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

,你會得到你所尋求的結果。

共有:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

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

</xsl:stylesheet>