2012-06-02 181 views
27

之间的所有元素我有一个下面的XML:的XPath选择两个特定元素

<doc> 
    <divider /> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <p>text</p> 
    <divider /> 
    <p>text</p> 
    <p>text</p> 
    <divider /> 
    <p>text</p> 
    <divider /> 
</doc> 

我想选择第一分隔元件后所有的p节点,直到分频器元件的下一次出现。我试着用下面的xpath:

//divider[1]/following-sibling::p[following::divider] 

但问题是它选择所有p元素之前最后一个divider元素。我不知道如何使用XPath 1.

回答

24

概念相同bytebuster,但不同的XPath:

/*/p[count(preceding-sibling::divider)=1] 
+0

好主意! 'count'比较习惯,因为'1'只使用一次。 – bytebuster

4

做关于选择具有完全相同一个元素dividerpreceding-sibling所有p什么?

//doc/p[preceding-sibling::divider[1] and not (preceding-sibling::divider[2])] 
14

这是一个普遍的XPath表达式

/*/divider[$k] 
    /following-sibling::p 
     [count(.|/*/divider[$k+1]/preceding-sibling::p) 
     = 
     count(/*/divider[$k+1]/preceding-sibling::p) 
     ] 

如果替代$k1则完全通缉选择了p个节点。

如果替代$k2然后第二和第三divider,...等等之间的所有p元素

说明

这是Kayessian的XPath的一个简单的应用程序1.0公式节点集交集:

$ns1[count(.|$ns2) = count($ns2)] 

se将属于两个的所有节点引导到节点集$ns1$ns2

在这种特定的情况下,我们代替$ns1有:

/*/divider[$k]/following-sibling::p 

,我们用替代$ns2

/*/divider[$k+1]/preceding-sibling::p 
+0

+1 Kayessian方法的很好的实现。 – Cylian

+0

@Cylian:不客气。 –

4

我觉得有一个更简单,也许更快的解决方案:你想要的所有前面的兄弟姐妹具有至少一个前面的兄弟分配器的第二分配器:

/doc/divider[2]/preceding-sibling::p[preceding-sibling::divider] 

当然,如果你想找到第二和第三个分隔线之间的分支,它会变得更复杂一点:那么你想要更像Daniel Haley的解决方案。