XPath选择,同时排除具有某些属性值的元素

时间:2010-09-09 20:30:38

标签: xpath filter attributes

我在这里的第一篇文章 - 这是一个很棒的网站,我会尽我所能尽可能多地回馈。

我看到以下问题的不同表现形式;但是我的解决方法似乎没有用。

考虑这个简单的树:

<root>
    <div>
        <p>hello</p>
        <p>hello2</p>
        <p><span class="bad">hello3</span></p>
    </div>
</root>

我想提出一个XPath表达式,它将选择“div”的所有子节点,除了,用于“class”属性等于“bad”的元素。

以下是我的尝试:

/root/div/node()[not (@class='bad')]

......但这似乎不起作用。

我在这里缺少什么?

干杯,
艾萨克

4 个答案:

答案 0 :(得分:3)

使用提供的XML文档测试XPath here时,XPath似乎确实选择了没有属性class="bad"的所有子节点 - 这些都是<p>个元素在文件中。

您将注意到,具有此类属性的唯一子节点是<span>,确实没有被选中。

您是否希望不选择p周围的span节点?

答案 1 :(得分:1)

我一直在编写一个Java程序中的XPath。如果要选择没有class =“bad”的节点(即<span>节点,而不是周围的<p>节点),可以使用:

/root/div/descendant::*[not (@class='bad')]

否则,如果要选择没有class ='bad'的子节点的

节点,可以使用以下内容:

/root/div/p/*[not (@class='bad')]/..

..部分选择直接父节点。

答案 2 :(得分:0)

身份转换只匹配并复制所有内容:

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

但是你添加了一个更具体匹配你想要排除的模式的空变换:

 <xsl:template match="span[@class='bad']" />

(如果您想更明确地了解哪一个具有优先权,您还可以添加优先级。)

答案 3 :(得分:0)

欢迎来到SO,Isaac!

我试试这个:

/root/div/*[./*[@class != "bad"]]

这应该选择*元素的所有子元素(div),这些元素没有具有class属性等于bad的后代元素。

修改

根据@Alejandros评论:

/root/div/*[not(*/@class "bad")]