2012-10-05 73 views
2

我在使用XLTS解析XML文件時遇到問題。具有指定屬性的XSLT轉換刪除節點

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pl"> 
    <body style="margin-top: 0px;"> 
    <a name="top"/> 
    <a name="menu"> </a> 
    <a href="cool html"> </a> 
    <table width="100%" cellspacing="0" cellpadding="2" border="0" class="aws_border sortable"/> 
    </body> 
    </html> 

,我需要刪除所有節點與<a name="something"> </a>,同時保留在文件<a href>節點和其他節點。

我已經試過

<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 
    <xsl:template match="body"> 
    <xsl:for-each select="a"> 
     <xsl:if test="@href != '' "> 
    <xsl:copy-of select="."/> 
    </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
    </xsl:stylesheet> 

但它僅保留<a href >節點,並刪除所有其他節點。

+1

一些建議,除非真的有必要,否則不要使用for-each! (例如:用於訪問兄弟節點等)。嘗試使用'<模板匹配=「」>'(像Tomalak的答案)這使代碼可讀和簡單:) –

回答

4

保留所有的節點,改變只有少數始終是這樣的:

  1. 您使用的身份模板。它複製(「保留」)所有不處理的節點。
  2. 您應爲每個應處理不同的節點編寫另一個模板。
  3. 您抵制使用<xsl:for-each>的衝動。你不需要它。

XSLT:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml" 
> 

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

    <!-- empty template to remove <a name="..."> specifically -->  
    <xsl:template match="xhtml:a[@name]" /> 

</xsl:stylesheet> 

就是這樣。

第3點其實很重要。避免在您編寫的所有XSLT中使用<xsl:for-each>。它看起來很熟悉而且很有幫助,但事實並非如此。它的使用傾向於導致難以重用的笨重,單片,深層嵌套的XSLT代碼。

總是試圖更喜歡<xsl:template><xsl:apply-templates>而不是<xsl:for-each>

+0

謝謝你的答案,但它不工作 - >它保留所有節點。 –

+1

@Tomasz你說得對,我忘了輸入中的XML命名空間。現在修復。 – Tomalak