XSLT Transformation删除具有指定属性的节点

时间:2012-10-05 06:51:29

标签: xml xslt transformation

我在使用XLTS解析XML文件时遇到问题。

    <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 个答案:

答案 0 :(得分:4)

保留所有节点并仅更改少数节点总是如下:

  1. 您使用身份模板。它复制(“保留”)所有未处理的节点。
  2. 您为每个应该以不同方式处理的节点编写另一个模板。
  3. 你抵制使用<xsl:for-each>的冲动。你不需要它。
  4. 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>