2014-09-26 12 views
8

Điều tôi cần không hoàn toàn phù hợp với các bài viết khác của một tựa đề tương tự.Biểu thức độc quyền hoặc nút cài đặt XPath 1.0

Tôi cần, sử dụng Xpath 1, để có thể nhận nút a hoặc nút b, theo thứ tự đó, theo thứ tự đó. Tức là, nút a nếu nó tồn tại, nếu không, nút b.

một biểu thức XPath như:

expression | expression

sẽ làm cho tôi cả trong trường hợp cả hai đều tồn tại. đó không phải là điều tôi muốn.

tôi có thể đi:

(expression | expression)[last()]

mà trên thực tế gget tôi những gì tôi cần (trong trường hợp của tôi), nhưng có vẻ là một chút không hiệu quả, bởi vì nó sẽ đánh giá cả hai mặt của biểu trước kết quả cuối cùng được chọn. Tôi đã hy vọng cho một biểu thức đó sẽ ngừng làm việc một khi phía bên trái thành công.

Một ví dụ cụ thể hơn về XML

<one> 
    <two> 
    <three>hello</three> 
    <four>bye</four> 
    </two> 
    <blahfive>again</blahfive> 
</one> 

và xpath mà làm việc (nhưng không hiệu quả):

(/one/*[starts-with(local-name(.), 'blah')] | .)[last()]

Để được rõ ràng, tôi muốn lấy các nút con trực tiếp của 'một' bắt đầu bằng 'blah'. Tuy nhiên, nếu nó không tồn tại, tôi chỉ muốn nút hiện tại. Nếu nút 'blah' không tồn tại, tôi không muốn nút hiện tại.

Có cách nào hiệu quả hơn để đạt được điều này không?

+1

+1 Thú vị câu hỏi và IMHO một giải pháp rất thanh lịch cho nó. Bạn có thể giải thích lý do tại sao bạn quan tâm đến hiệu suất trong trường hợp này? Đánh giá từ kinh nghiệm của tôi, mất hiệu suất trong các bảng XSLT do các nguyên nhân khác gây ra. –

+0

Xin chào. Nó thực sự cho một ứng dụng java. Ứng dụng sử dụng các biểu thức xpath (được tải từ tệp cấu hình) để trích xuất các giá trị từ một tài liệu XML. Ứng dụng sẽ nhận được nhiều tài liệu như vậy mỗi phút, vì vậy hiệu quả là quan trọng để cải thiện (hoặc thậm chí đạt được) đáng tin cậy thông qua đặt. – svaens

+2

Nếu điều này được nhúng vào Java, bạn sẽ/có thể có quyền kiểm soát các biểu thức con bằng cách thực hiện rõ ràng XPath thứ hai chỉ khi kết quả đầu tiên không mang lại kết quả, đúng không? –

Trả lời

1

Tôi cần, sử dụng Xpath 1, để có thể nhận nút a hoặc nút b, một cách dễ dàng, theo thứ tự đó. Tức là, nút a nếu nó tồn tại, nếu không, nút b.

một biểu thức XPath như:

expression | expression

sẽ làm cho tôi cả trong trường hợp cả hai đều tồn tại. đó không phải là điều tôi muốn.

tôi có thể đi:

(expression | expression)[last()]

mà trên thực tế gget tôi những gì tôi cần (trong trường hợp của tôi),

Tuyên bố này là không đúng sự thật.

Đây là một ví dụ.Hãy để chúng tôi có tài liệu này XML:

<one> 
    <a/> 
    <b/> 
</one> 

expression1 là:

/*/a 

expression2 là:

/*/b 

biểu tổng hợp của bạn:

(Expression1 | Expression2)[last()] 

khi chúng ta thay thế hai biểu thức trên là:

(/*/a | /*/b)[last()] 

Và biểu hiện này thực sự chọn b - không a - vì b là cuối cùng của hai theo thứ tự tài liệu.

Bây giờ, đây là một biểu hiện mà chỉ a chọn nếu nó tồn tại, và chọn b chỉ khi a không tồn tại - không phân biệt thứ tự tài liệu:

/*/a | /*/b[not(/*/a)] 

Khi biểu thức này được đánh giá trên XML tài liệu ở trên, nó chọn a, bất kể thứ tự tài liệu của nó - thử trao đổi trong tài liệu XML phía trên các địa điểm ab để xác nhận rằng trong cả hai trường hợp, phần tử được chọn là a.

Để tóm tắt, một biểu thức mà chọn nút truy nã bất kể thứ tự bất kỳ tài liệu là:

Expression1 | Expression2[not(Expression1)] 

Chúng ta hãy áp dụng biểu hiện chung này trong trường hợp của bạn:

expression1 là:

/one/*[starts-with(local-name(.), 'blah')] 

Expression2 là:

self::node() 

Các muốn biểu (sau khi thay expression1 và expression2 trong biểu thức chung ở trên) là:

/one/*[starts-with(local-name(.), 'blah')] 
| 
    self::node()[not(/one/*[starts-with(local-name(.), 'blah')])] 
Các vấn đề liên quan