2012-04-16 50 views
0

我對XSL轉型非常陌生這裏是問題。如果我有這樣的XML文件:使用XSLT刪除XML中未定義級別的重複條目

<root> 
     <node id="a"> 
      <section id="a_1"> 
       <item id="0"> 
        <attributes> 
         <color>Red</color> 
        </attributes> 
       </item> 
      </section> 
      <section id="a_2"> 
       <item id="0"> 
        <attributes> 
         <color>Red</color> 
        </attributes> 
       </item> 
      </section>    
     </node> 

     <node id="b"> 
      <section id="b_1"> 
       <user id="b_1a"> 
        <attribute> 
         <name>John</name> 
        </attribute> 
       </user> 

       <user id="b_1b"> 
        <attribute></attribute> 
       </user> 

       <user id="b_1a"> 
        <attribute> 
         <name>John</name>  
        </attribute> 
       </user> 
      </section> 
     </node> 
</root> 

,我想輸出是這樣的:

<root> 
     <node id="a"> 
      <section id="a_1"> 
       <item id="0"> 
        <attributes> 
         <color>Red</color> 
        </attributes> 
       </item> 
      </section> 
      <section id="a_2"> 
       <item id="0"> 
        <attributes> 
         <color>Red</color> 
        </attributes> 
       </item> 
      </section>    
     </node> 

     <node id="b"> 
      <section id="b_1"> 
       <user id="b_1a"> 
        <attribute> 
         <name>John</name> 
        </attribute> 
       </user> 

       <user id="b_1b"> 
        <attribute></attribute> 
       </user> 

      </section> 
     </node> 
</root> 

而問題是我不知道的水平有多深能去,但只要它在同一層次上,有重複的,我們刪除它。 這是可能做到的。我一直試圖解決這一整天,並沒有得到任何線索。 任何幫助將不勝感激。

歡呼聲, 約翰

回答

2

試試這個:也

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <!--If you want to remove any duplicate element (not just user, 
    change the match to: match="*[@id = preceding::*/@id]"--> 
    <xsl:template match="user[@id = preceding::user/@id]"/> 

</xsl:stylesheet> 

,我不知道你「在同一水平上」的意思是什麼,但如果元素名稱也必須匹配,使用這個模板:(注意:此模板撒克遜9.3工作,但Xalan中或撒克遜6.5.5沒有)

<xsl:template match="*[@id = preceding::*[name() = name(current())]/@id]"/> 

UPDATE:這裏有一個似乎在Xalan和Saxon 6.5.5中工作的模板:

<xsl:template match="*[@id = preceding::*/@id]"> 
    <xsl:if test="not(@id = preceding::*[name() = name(current())]/@id)"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:if> 
    </xsl:template> 
+0

非常感謝!它現在有效 – John 2012-04-17 03:25:30