2010-10-01 60 views
12

考虑选择父元素这样的:XPATH:只有当子元素不包含一定值

<element_1> 
    <element_2>Text</element_2> 
    <element_3> 
     <element_4> 
      <element_5>Text with @ in Value</element_5> 
     </element_4> 
     <element_4> 
      <element_5>Test Text</element_5> 
     </element_4> 
    </element_3> 
    <element_6> 
     <element_7> 
      <element_8>0</element_8> 
... 

如何选择做包含element_5一个“@” element_1的所有实例?

+0

好问题(+1)。查看我的答案,获取一个通用的XPath表达式,该表达式选择任何文档中的所有必需元素 - 当文档的结构未预先知道时。 – 2010-10-01 21:53:38

回答

14
element_1[not(contains(element_3/element_4/element_5,'@'))] 

这被解释为

element_1[       #select elements named "element_1" 
    not(contains(     #that do not contain 
    element_3/element_4/element_5, #children in this hierarchy 
    '@'        #the character @ 
)) 
] 
+1

这是否需要在element_1之前引导//? – Snekse 2010-10-01 20:55:53

+0

取决于您是否想在任何级别匹配element_1,或者它是否始终是DOM的根。 – dty 2010-10-01 21:21:26

+1

另请注意,此解决方案假定element_5总是位于element_4的正下方,而element_4总是位于element_3的正下方,而element_3又位于element_1的正下方。其他两种解决方案假定element_5可以出现在element_1下的任何级别。 – dty 2010-10-01 21:23:02

0
element1[not(contains(.//element_5, '@'))] 
+0

downvote是怎么回事? – 2010-10-01 22:21:41

6

我的XPath是有点生疏,但这样的事情:

//element_1[.//element_5[not(contains(., "@"))]] 
+0

我们是一个挑剔的位,并且当架构已经很熟悉时不推荐'//'操作符... – 2010-10-01 21:49:10

+0

这很好。 OP没有具体说明这一点。 – dty 2010-10-01 21:58:45

+1

为什么降级?至少有正派留言说明你为什么排名下降,不管你是谁。 – dty 2010-10-01 21:59:05

4

如何选择的 所有实例element_1在element_5中不包含'@' ?

使用

//element_1[not(.//element_5[contains(.,'@')])] 

在英语中,这意味着:选择文档中的所有元素"element_1"没有一个"element_5"后裔,其字符串值包含字符串'@'

我只使用//缩写,因为XML文件的结构不清楚。

我总是建议在可能的情况下总是避免使用//的缩写,否则这可能会导致效率非常低的XPath评估。

+1

@ Mads-Hansen:感谢您的编辑,但“后代”是一个有效的英文单词。 – 2010-10-02 01:41:23

相关问题