2011-03-16 65 views
1

我有类似这样的XML结构:XPath表达式来选择父母带着两个孩子已经儿童

<Header> 
    <ElementA> 
     <ElementB> 
      <ElementC/> 
      <ElementC/> 
     </ElementB> 
     <ElementB/> 
    </ElementA> 
</Header> 

其中<ElementB>可能有<ElementC>序列,或者可以没有。

我可以选择<ElementA>节点,它有两个<ElementB>,/Header/ElementA/ElementB/following-sibling::ElementB。我可以选择<ElementA>节点,其中包含使用/Header/ElementA/ElementB[ElementC]包含<ElementC><ElementB>节点。

但我怎么选择其中包含<ElementB>其中包含一个<ElementC>紧接着又<ElementB>含有另一<ElementC><ElementA>节点。事情是这样的:

<Header> 
    <ElementA> 
     <ElementB> 
      <ElementC/> 
      <ElementC/> 
     </ElementB> 
     <ElementB> 
      <ElementC/> 
      <ElementC/> 
     </ElementB> 
    </ElementA> 
</Header> 
+0

@ John-Saunders:你可能会表现出某种尊重并选择最好的答案(我认为这显然是@ Robert-Rossney的答案)。 – 2011-03-20 04:53:11

+1

@Dimitre:如果我在理解后接受答案,它会表现出最大的尊重。我很接近,我没有忘记。 – 2011-03-21 18:20:45

回答

9

注意,你没有明确搜索以下同辈轴。这两种模式将返回相同的结果:

foo[bar/following-sibling::bar] 

foo[bar[2]] 

所以你的模式可以是简单的:

​​

它会发现有两个或两个以上ElementA元素ElementB孩子,每个孩子都有一个ElementC孩子。

+0

非常好。一个悖论:你可能不需要'ElementC [2]'上的谓词,因为他没有指定存在多于一个'ElementC',尽管他的例子显示了不止一个。 – 2011-03-16 05:45:54

+0

啊,很对。我会解决这个问题。 – 2011-03-16 06:40:16

+1

+1最佳答案。如果有**至少两个**,那么还有一个。所有这些**都不会将邻近点**加入计数中。 – 2011-03-16 19:04:15

3

我可能只是回答我自己的问题:

/Header/ElementA[ElementB[ElementC]/following-sibling::ElementB[ElementC]] 

似乎工作。之前看起来没有工作的原因是,我的文件,所有88000行都没有出现这种模式。这可能表示产生它的代码中的错误,而不是我XPATH表达式中的错误。

+0

@ John-Saunders:你可能会表现出某种尊重并选择最好的答案(我认为这显然是@ Robert-Rossney的答案)。 – 2011-03-20 04:52:51

2

嵌套谓词干得不错:

/Header/ElementA[ElementB[following-sibling::ElementB/ElementC]/ElementC]