2012-03-10 69 views
0

我有一個這樣的XML:的XPath exlude節點及其後代

<Root xmlns:test1="http://www.test1.com" xmlns:test2="http://www.test2.com" Attr="root"> 
    <test1:Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3"> 
    <child11 Attribute11="c11">Element11</child11> 
    </test1:Child1> 
    <test2:Child2 Attribute2="c2"> 
    <child21 Attribute21="c21"> 
     <child211 /> 
     <child212 /> 
     <child213 /> 
    </child21> 
    <child22 Attribute22="c22">Element22</child22> 
    </test2:Child2> 
    <test2:Child3 Attribute3="c3"> 
    <child31>Element31</child31> 
    </test2:Child3> 
</Root> 

我想編寫一個XPath,這樣我會得到除了child21元素及其後代選擇所有。因此,輸出應該如下所示:

<Root xmlns:test1="http://www.test1.com" xmlns:test2="http://www.test2.com" Attr="root"> 
    <test1:Child1 Attribute1="c1" Bttribute="c2" Cttribute="c3"> 
    <child11 Attribute11="c11">Element11</child11> 
    </test1:Child1> 
    <test2:Child2 Attribute2="c2"> 
    <child22 Attribute22="c22">Element22</child22> 
    </test2:Child2> 
    <test2:Child3 Attribute3="c3"> 
    <child31>Element31</child31> 
    </test2:Child3> 
</Root> 

這是什麼xpath代碼?

非常感謝

回答

0

XPath來排除child21

/Root/*/*[not(local-name()='child21')] 

這給出結果作爲

child11 
child22 
child31 

這個按照您的要求修改。

1

XPath從不修改它選擇的節點,它只是選擇它們。如果您的選擇包含(說)Root元素,那麼在序列化時它將包含輸入文檔的所有元素,即使您只選擇該單個元素。

您可以通過

//*[not(ancestor-or-self::child21)] 

迭代是不必須在他們的祖先或自身軸child21的所有元素,但如果你想生成所示的結果,是不是非常有用的。

是微不足道的過濾掉元素及其使用XSLT的後代,只是有一個身份模板,並添加一個模板

<xsl:template match="child21"/> 

,它放棄輸入的一個分支,但你不能做到這一點與單獨的XPath。

0

一個的XPath將選擇的節點,但如果你wanty實際複製XML跳過某些元素,你需要的是一個XSLT - 這將產生你想要的輸出:

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

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

    <!-- Template to skip 'child21' elements --> 
    <xsl:template match="child21"> 
    </xsl:template> 

</xsl:stylesheet>