xpath tìm nếu nút tồn tại


201

Sử dụng truy vấn xpath làm thế nào để bạn tìm thấy nếu một nút (thẻ) tồn tại?

Ví dụ: nếu tôi cần đảm bảo một trang web có cấu trúc cơ bản chính xác như / html / body và / html / head / title


Có lẽ tốt hơn là sử dụng Lược đồ XML với chỉ dẫn các yếu tố bắt buộc? Vì vậy, kiểm tra xem một tài liệu sử dụng nó hay không.
abatishchev

Câu trả lời:


321
<xsl:if test="xpath-expression">...</xsl:if>

ví dụ

<xsl:if test="/html/body">body node exists</xsl:if>
<xsl:if test="not(/html/body)">body node missing</xsl:if>

41
Ngạc nhiên ở mức xếp hạng cao như vậy cho rằng câu hỏi không chỉ định sử dụng XSLT.
tjmoore

Điều này thật tuyệt vời nhưng nếu tôi muốn kiểm tra xem nó có tồn tại HOẶC trống không?
SearchForKnowledge

3
@SearchForKnowledge, có lẽ bạn nên hỏi rằng đó là một câu hỏi mới tại SO, nhưng là một hướng dẫn nhanh: html/body and not(html/body/node())(nghĩa là chỉ kiểm tra nếu nó tồn tại và nó không chứa bất kỳ nút con hoặc nút văn bản nào).
Abel

71

Hãy thử biểu thức sau: boolean(path-to-node)


3
Đây chính xác là những gì tôi cần khi sử dụng XPath trong Python với lxml.
Iain Samuel McLean Elder

1
Điều này có hiệu quả khi xây dựng Điều kiện quy tắc và Hành động quy tắc trong InfoPath 2010
Merenzo

3
Đây là câu trả lời đúng theo nghĩa đây thực sự là một truy vấn XPath, không giống như hầu hết các câu trả lời khác.
Paul Etherton

48

Patrick là chính xác, cả trong việc sử dụng xsl:ifvà trong cú pháp để kiểm tra sự tồn tại của một nút. Tuy nhiên, như phản hồi của Patrick ngụ ý, không có xsl tương đương với if-then-other, vì vậy nếu bạn đang tìm kiếm thứ gì đó giống như if-then-other, bạn thường sử dụng tốt hơn xsl:choosexsl:otherwise. Vì vậy, cú pháp ví dụ của Patrick sẽ hoạt động, nhưng đây là một thay thế:

<xsl:choose>
 <xsl:when test="/html/body">body node exists</xsl:when>
 <xsl:otherwise>body node missing</xsl:otherwise>
</xsl:choose>

+1 để ghi chú if-then-else, còn về cái gì if-else if-else? Trong câu trả lời của davenpcj tôi có thể đặt test="somexpath"thứ 2 khi nào thực hiện if-else if-elsekhông?
AabinGunz

3
@Abhishek Có, bạn có thể đặt thêm xsl: khi có các điều kiện khác và có câu lệnh đa nhánh. Hãy nghĩ về nó giống như một CHỌN hơn là một if-then-other, với xsl: nếu không thì là mặc định :.
davenpcj

Điều này thật tuyệt vời nhưng nếu tôi muốn kiểm tra xem nó có tồn tại HOẶC trống không?
SearchForKnowledge

13

Có thể tốt hơn để sử dụng một lựa chọn, không phải gõ (hoặc có thể gõ nhầm) biểu thức của bạn nhiều lần và cho phép bạn theo dõi các hành vi khác nhau.

Tôi rất thường sử dụng count(/html/body) = 0, vì số lượng nút cụ thể thú vị hơn tập hợp. Ví dụ ... khi có nhiều hơn 1 nút phù hợp với biểu thức của bạn.

<xsl:choose>
    <xsl:when test="/html/body">
         <!-- Found the node(s) -->
    </xsl:when>
    <!-- more xsl:when here, if needed -->
    <xsl:otherwise>
         <!-- No node exists -->
    </xsl:otherwise>
</xsl:choose>

Như đã chỉ ra trong đoạn mã trên, thêm xsl: khi các mệnh đề có thể được thêm vào để thay đổi hành vi và xử lý nhiều điều kiện theo nhiều cách khác nhau.
davenpcj

count(/html/body) = 0 Thiên tài ! : DI sử dụng nó như /html[count(/body)=0]/someNodeđể chọn someNodekhi nào /body(hoặc bất cứ thứ gì) bị thiếu
Stefan Rogin

1
@clickstefan, /html[count(/body)=0]sẽ không bao giờ chọn bất cứ thứ gì, không thể có hai nút gốc trong XML. Có lẽ bạn có nghĩa là /html[count(body)=0], sẽ giống như /html[not(body)], hoặc /html[not(exists(body))].
Abel

@Abel yes, / html [Count (// body) = 0] hoặc cách bạn nói, đáng xấu hổ nhưng vâng tôi đã không đưa ra một ví dụ thích hợp
Stefan Rogin

4

Tôi làm việc trong Ruby và sử dụng Nokogiri, tôi tìm nạp phần tử và xem thử kết quả có phải không.

require 'nokogiri'

url = "http://somthing.com/resource"

resp = Nokogiri::XML(open(url))

first_name = resp.xpath("/movies/actors/actor[1]/first-name")

puts "first-name not found" if first_name.nil?

3

Một biến thể khi sử dụng xpath trong Java bằng cách sử dụng Count ():

int numberofbodies = Integer.parseInt((String) xPath.evaluate("count(/html/body)", doc));
if( numberofbodies==0) {
    // body node missing
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.