2010-11-02 32 views
11

Tôi có truy vấn XPath đang thực hiện những gì tôi muốn, cụ thể là chọn liên kết 'họ' & 'tên đã cho' với các biến vị ngữ đã cho (Thực ra là hoặc là tôi cần, nhưng công đoàn hoạt động tốt):XPath chọn nhiều phần tử có biến vị ngữ

/header/authors/surname[./text() and @id='1'] 
| 
/header/authors/given-names[./text() and @id='1'] 

Tuy nhiên điều này dường như quá dài dòng với tôi và tôi cảm thấy rằng chúng ta có thể làm điều gì đó gọn gàng hơn như:

/header/authors/(surname|given-names)[./text() and @id='1'] 

... nhưng điều này phiên bản không phải là XPath hợp lệ.

Bất cứ ai có thể cho tôi biết cách viết văn bản XPath gốc không đòi hỏi đường dẫn đầy đủ phải được viết hai lần?

Cảm ơn

Richard

+0

Bạn có ý nghĩa gì bởi "một trong hai hoặc"? –

+0

@Alejandro: Với một id, phần tử được yêu cầu có thể là 'họ' hoặc 'tên đã cho'. Đó là điều tôi đang cố nói. Tôi nghĩ đó là công đoàn mà tôi cần. –

Trả lời

24

Thứ nhất, đây là hợp lệ XPath 2.0:

/header/authors/(surname|given-names)[./text() and @id='1'] 

Thứ hai, XPath này 1.0:

/header/authors/*[self::surname|self::given-names][text()][@id='1'] 
+1

Điều này thật tuyệt vời và tôi chuẩn bị +1 nó. Tuy nhiên, trong phiên bản XPath 1.0, tốt nhất là không sử dụng '|' bên trong vị từ. Toán tử đúng là 'hoặc'. Trong trường hợp này biểu thức vẫn chọn các nút mong muốn, nhưng trong các trường hợp khác thay thế 'hoặc' bằng' | 'không tạo ra một biểu thức tương đương. 1, dù sao đi nữa. –

+1

@Dimitre: Bạn đúng về toán tử tập hợp công đoàn '|', nhưng tôi đã sử dụng nó ** trong trường hợp này **, bởi vì cả hai thuật ngữ là tập hợp nút (và vì ngắn gọn là khóa). Cũng vậy với chuỗi dự báo. –

+0

Câu trả lời này giải thích cả lý do tại sao tôi cảm thấy rằng tôi có thể sử dụng '(họ tên | tên)' (dự án hiện tại không sử dụng XPath 2.0) và cũng cung cấp một thay thế XPath 1.0 tuyệt vời. Cảm ơn. –

4

Làm thế nào về

/header/authors/*[(name() = "surname" or name()="given-names") and ./text() and @id='1'] 
+0

Điều đó sẽ hiệu quả, nhưng nếu không thì nó đẹp hơn ... – annakata

+0

Cảm ơn câu trả lời của bạn. Nó tiết kiệm được bằng văn bản con đường ra hai lần, nhưng vẫn còn hơi khó sử dụng so với những gì tôi đã có trong tâm trí. –

2

Ngoài của Alejandro và câu trả lời tốt Seva của, thay thế khác là

(/header/authors/surname | /header/authors/given-names)[text() and @id='1'] 

này có giá trị trong XPath 1.0. Nó vẫn là một chút dư thừa, nhưng gọn gàng hơn so với phiên bản dài trong câu hỏi của bạn.

Một lựa chọn hơn nữa sẽ được khai báo một biến cho các yếu tố họ và một biến cho các yếu tố đưa tên tuổi, và sau đó

($surnames | $given-names)[text() and @id='1'] 

Đó có lẽ sẽ là còn trong tổng số, nhưng dễ đọc hơn so với ở trên.

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