2009-10-12 111 views
2

中第一次出現我有XML是這樣的:XSLT:刪除所有,但給定節點

<MyXml> 
    <RandomNode1> 
    <TheNode> 
     <a/> 
     <b/> 
     <c/> 
    </TheNode> 
    </RandomeNode1> 
    <RandomNode2> 
    </RandomNode2> 
    <RandomNode3> 
    <RandomNode4> 
     <TheNode> 
     <a/> 
     <b/> 
     <c/> 
     </TheNode>  
    </RandomNode4> 
    </RandomNode3> 
</MyXml> 

<TheNode>出現在整個XML,但並不在同一水平,經常在其他節點深。我需要做的是消除所有出現的<TheNode>除第一個。其餘的是多餘的,佔用空間。 XSL可以做到這一點是什麼?

我有這樣的事情:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

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

    <xsl:template match="//TheNode[position()!=1]"> 
    </xsl:template> 

</xsl:stylesheet> 

但是,這是不正確的。有什麼建議麼?

回答

4
<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="node() | @*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node() | @*"/> 
    </xsl:copy> 
    </xsl:template> 
    <xsl:template match="TheNode[preceding::TheNode]"/> 
</xsl:stylesheet> 
+0

沒有必要爲起點' //模式中的操作符。 – 2011-01-24 17:57:25

2

//TheNode[position()!=1]不起作用,因爲在這裏,position()相對於每個<TheNode>的父上下文。它會選擇所有<TheNode>,這些不是其各自的父母中的第一個。

但是你是在正確的軌道上。你什麼意思

 
(//TheNode)[position()!=1] 

注意括號 - 它們導致謂詞分別適用於整個選擇的節點集,而不是到每個節點。

不幸的是,即使這是有效的XPath表達式,它作爲匹配模式無效。匹配模式必須對單個節點有意義(適用),它不能是選擇表達式。

所以@ Alohci的解決方案,

 
//TheNode[preceding::TheNode] 

是表達你想要的正確途徑。

0

的圖案之外的做法是:

<xsl:template match="TheNode[generate-id() 
          != generate-id(/descendant::TheNode[1)]"/> 

注意:它更可能是一個絕對的表達被optimizated相對錶達inteads像preceding::TheNode