2009-11-24 69 views
17

這裏的樣本數據:XPath表達式來選擇除特定列表以外的所有XML子節點?

<catalog> 
    <cd> 
     <title>Empire Burlesque</title> 
     <artist>Bob Dylan</artist> 
     <country>USA</country> 
       <customField1>Whatever</customField1> 
       <customField2>Whatever</customField2> 
       <customField3>Whatever</customField3> 
     <company>Columbia</company> 
     <price>10.90</price> 
     <year>1985</year> 
    </cd> 
    <cd> 
     <title>Hide your heart</title> 
     <artist>Bonnie Tyler</artist> 
     <country>UK</country> 
       <customField1>Whatever</customField1> 
       <customField2>Whatever</customField2> 
     <company>CBS Records</company> 
     <price>9.90</price> 
     <year>1988</year> 
    </cd> 
    <cd> 
     <title>Greatest Hits</title> 
     <artist>Dolly Parton</artist> 
     <country>USA</country> 
       <customField1>Whatever</customField1> 
     <company>RCA</company> 
     <price>9.90</price> 
     <year>1982</year> 
    </cd> 
</catalog> 

說我要選擇,除了價格和年份的元素應有盡有。我期望寫下類似的東西,這顯然不起作用。

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
    <html> 
    <body> 
    <xsl:for-each select="//cd/* except (//cd/price|//cd/year)"> 
    Current node: <xsl:value-of select="current()"/> 
    <br /> 
    </xsl:for-each> 
    </body> 
    </html> 
</xsl:template> 
</xsl:stylesheet> 

請幫我找一種排除某些子元素的方法。

回答

37
<xsl:for-each select="//cd/*[not(self::price or self::year)]"> 

但實際上這是不好的,也是不必要的複雜。更好:

<xsl:template match="catalog"> 
    <html> 
    <body> 
     <xsl:apply-templates select="cd/*" /> 
    </body> 
    </html> 
</xsl:template> 

<!-- this is an empty template to mute any unwanted elements --> 
<xsl:template match="cd/price | cd/year" /> 

<!-- this is to output wanted elements --> 
<xsl:template match="cd/*"> 
    <xsl:text>Current node: </xsl:text> 
    <xsl:value-of select="."/> 
    <br /> 
</xsl:template> 

避免<xsl:for-each>。幾乎所有的時間都是錯誤的工具,應該用<xsl:apply-templates><xsl:template>來代替。

上述工作是因爲匹配表達的特異性。 match="cd/price | cd/year"match="cd/*"更具體,所以它是cd/pricecd/year元素的首選模板。不要試圖排除節點,讓他們來丟棄它們來處理它們。

+2

感謝您的解釋。 – 2009-11-24 19:33:46

9

我開始嘗試的東西像

"//cd/*[(name() != 'price') and (name() != 'year')]" 

,或者你只是做正常的遞歸模板匹配與<xsl:apply-templates/>,然後有<price/>空模板和<year/>元素:

<xsl:template match="price"/> 
<xsl:template match="year"/> 
相關問題