2012-03-10 73 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>