2010-06-09 26 views
15

ancestor::foo[bar[@attr="val"]]XPath để tìm phần tử tổ tiên gần nhất chứa phần tử có thuộc tính với một giá trị nhất định

Tôi nghĩ điều này sẽ hiệu quả, nhưng không phải vậy. Tôi cần tìm phần tử foo gần nhất ở trên cây có phần tử con bar, lần lượt có thuộc tính attr của val.

+0

Bạn nhận được gì? –

+0

Không có gì. Nó không khớp với phần tử tôi mô tả. Biểu thức đó có hoạt động không? –

+8

Vui lòng cung cấp tài liệu XML (tối thiểu) mà tài liệu này "không hoạt động". Chúng tôi chỉ biết rằng bạn đang "đặt tay vào túi và không tìm thấy những gì bạn muốn ở đó" nhưng chúng tôi không biết "những gì có trong túi" :) –

Trả lời

28

này nên làm việc:

//*[ancestor::foo[bar[@attr="val"]]] 

hoặc cách khác

root/foo/bar[ancestor::foo[bar[@attr="val"]]] 

phù hợp với thứ hai <bar> yếu tố

<root> 
    <foo> 
     <bar attr="xxx"></bar> 
    </foo> 
    <foo> 
     <bar attr="val"></bar> 
    </foo> 
    <foo> 
     <bar attr="zzz"></bar> 
    </foo> 
</root> 
+4

Điều này thực sự trả lời câu hỏi? OP muốn chọn tổ tiên (foo) .. ví dụ này chọn hậu duệ (thanh) mà tổ tiên của nó khớp với một số tiêu chí. –

+3

Điều này không trả lời được câu hỏi. Không chắc chắn lý do tại sao nó đã được bỏ phiếu. – geoidesic

+1

@geoidesic vì nó rõ ràng giải quyết vấn đề OPs – Gordon

9

cập nhật để phản ánh một giải pháp dự định của OP.

câu trả lời See @ David

Đối với một xml mẫu dưới đây,

<root> 
<foo id="0"> 
    <bar attr="val"/> 
    <foo id="1"> 
     <bar attr="xxx"/> 
    </foo> 
    <foo id="2"> 
     <bar attr="val"> 
      <one>1</one> 
      <two> 
       <three>3</three> 
      </two> 
     </bar> 
    </foo> 
</foo> 

xpath hợp lệ trên trục ngược với <ba> là nút bối cảnh, một hợp lệ giải pháp là

./ancestor::foo[bar[@attr='val']][position() = 1] 

"./" là tùy chọn. vị trí() = 1 không phải là tùy chọn nếu không tổ tiên foo thỏa mãn các biến vị ngữ cũng sẽ được trả lại.

Cũ câu trả lời: bỏ qua

Đây là một câu hỏi cũ. nhưng bất cứ ai quan tâm, những điều sau đây sẽ giúp bạn có được câu hỏi ban đầu.

Xếp trục

//bar[@attr='val']/ancestor::*[position()=1] 

Forward trục

//*[child::bar[@attr='val']] 
+0

Sự đảo ngược của "tổ tiên" là "hậu duệ", không phải "con". "con" là đảo ngược của "cha mẹ" thay vì "tổ tiên" – wybe

+0

@wybe Tôi nghĩ rằng bạn đang bối rối hướng xpath trục với trái nghĩa của một trục. Bất kỳ trục nào tìm thấy các nút theo thứ tự tài liệu sau khi nút ngữ cảnh là một trục tiến. Một trục tìm các nút theo thứ tự tài liệu trước khi nút ngữ cảnh là một trục đảo ngược. Nếu điều đó không giải quyết những gì bạn dự định, bạn có thể vui lòng cung cấp những gì bạn thực sự có nghĩa là do đó. – santon

+0

@wybe Hãy tham khảo https://www.w3.org/TR/xpath/#axes và theo phần 2.4 Predicates – santon

1

Theo tôi câu trả lời tốt nhất được cung cấp bởi người đặt ra câu hỏi. Giải pháp của anh ta được cho là sẽ trả lại tất cả các foos của tổ tiên. Ông chỉ muốn gần nhất một trong đó là một với vị trí() = 1, do đó biểu hiện xpath của ông cần phải được sửa đổi để hơi:

ancestor::foo[bar[@attr="val"] and position() = 1] 

Nếu ông viết rằng ancestor::foo[bar[@attr="val"]] không trở về bất cứ điều gì, vì vậy ông có một số vấn đề khác trong xml của mình hoặc trong giả định của ông về yếu tố hiện tại của bối cảnh đánh giá XPath của ông.

Các câu trả lời khác (bắt đầu bằng //) không thực sự trả lời câu hỏi và thậm chí nếu chúng đáp ứng được nhu cầu của ai đó, vì vậy chúng không hiệu quả: họ chọn TẤT CẢ các phần tử trong tệp xml, áp dụng bộ lọc sau đó. Trong khi những gì xpath tương đối được đề xuất bởi tôi hoặc người đã hỏi câu hỏi này chỉ là tìm kiếm thông qua vài phần tử bắt đầu từ nút hiện tại đến cha mẹ và đó là cha mẹ, vv - nó sẽ rất hiệu quả ngay cả với các tệp XML lớn .

+0

Tôi đồng ý với đánh giá của bạn. Câu trả lời của tôi giải quyết vấn đề từ trên xuống và không giải quyết nó từ nút ngữ cảnh. Tôi sẽ cập nhật câu trả lời của tôi để phản ánh điều đó. cám ơn – santon

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