2012-06-02 33 views
27

Tôi có một xml sau:XPath chọn tất cả các yếu tố giữa hai yếu tố cụ thể

<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> 

Tôi muốn chọn tất cả các nút p sau yếu tố chia đầu tiên cho đến khi xuất hiện tiếp theo của nguyên tố chia. Tôi đã thử với xpath sau đây:

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

nhưng vấn đề là chọn tất cả phần tử p trước phần tử chia cuối cùng. Tôi không chắc chắn làm thế nào để làm điều đó bằng xpath 1.

Trả lời

24

Cùng khái niệm như bytebuster, nhưng xpath khác nhau:

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

Ý tưởng tuyệt vời! 'count' là thành ngữ hơn vì' 1' chỉ được sử dụng một lần. – bytebuster

4

gì về việc chọn lựa tất cả p có chính xác một yếu tố divider như preceding-sibling?

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

Đây là một biểu thức XPath chung:

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

Nếu bạn thay thế $k với 1 sau đó chính xác muốn Các nút p được chọn.

nếu bạn thay thế $k với 2 sau đó tất cả các yếu tố p giữa 2 và 3 divider, ..., vv

Giải thích:

Đây là một ứng dụng đơn giản của Kayessian XPath 1.0 công thức cho nút giao điểm nút:

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

se lects tất cả các nút thuộc về cả hai đến các nodesets $ns1$ns2.

Trong trường hợp cụ thể này, chúng tôi thay $ns1 với:

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

và chúng tôi thay $ns2 với:

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

+1 Triển khai thực hiện tốt '' phương thức Kayessian''. – Cylian

+0

@Cylian: Bạn được chào đón. –

4

Tôi nghĩ rằng có một giải pháp đơn giản hơn nhiều và có lẽ nhanh hơn: bạn muốn tất cả anh chị em trước của bộ chia thứ hai có ít nhất một bộ chia anh chị em trước:

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

Mọi thứ trở nên phức tạp hơn một chút, nếu bạn muốn tìm ký hiệu giữa ngăn thứ hai và thứ ba: thì bạn muốn một thứ gì đó giống như giải pháp của Daniel Haley hơn.

Các vấn đề liên quan