XPath: Làm thế nào để chọn các yếu tố dựa trên giá trị của chúng?


221

Tôi mới sử dụng XPath và đây có thể là một câu hỏi cơ bản. Vui lòng chịu đựng với tôi và giúp tôi giải quyết vấn đề. Tôi có một tệp XML như thế này:

<RootNode>
  <FirstChild>
    <Element attribute1="abc" attribute2="xyz">Data</Element>
  <FirstChild>
</RootNode>

Tôi có thể xác thực sự hiện diện của một <Element>thẻ với:

// Phần tử [@ property1 = "abc" và @ property2 = "xyz"]

Bây giờ tôi cũng muốn kiểm tra giá trị của thẻ cho chuỗi "Data". Để đạt được điều này, tôi đã nói với sử dụng:

// Phần tử [@ property1 = "abc" và @ property2 = "xyz" và Dữ liệu]

Khi tôi sử dụng biểu thức sau, tôi gặp lỗi sau:

Thông báo lỗi xác nhận: Không có nút phù hợp //Element[@attribute1="abc" and @attribute2="xyz" and Data]

Vui lòng cung cấp cho tôi lời khuyên của bạn cho dù biểu thức XPath tôi đã sử dụng có hợp lệ hay không. Nếu không, biểu thức XPath hợp lệ là gì?

Câu trả lời:


329

Điều kiện dưới đây:

//Element[@attribute1="abc" and @attribute2="xyz" and Data]

kiểm tra sự tồn tại của dữ liệu phần tử trong Phần tử chứ không phải dữ liệu giá trị phần tử.

Thay vào đó bạn có thể sử dụng

//Element[@attribute1="abc" and @attribute2="xyz" and text()="Data"]

25
//Element[@attribute1="abc" and @attribute2="xyz" and .="Data"]

Lý do tại sao tôi thêm câu trả lời này là tôi muốn giải thích mối quan hệ của .text().

Điều đầu tiên là khi sử dụng [], chỉ có hai loại dữ liệu:

  1. [number] để chọn một nút từ tập hợp nút
  2. [bool] để lọc một tập hợp nút từ tập hợp nút

Trong trường hợp này, giá trị được ước tính là boolean theo hàm boolean()và có một quy tắc:

Các bộ lọc luôn được đánh giá liên quan đến bối cảnh.

Khi bạn cần so sánh text()hoặc .với một chuỗi "Data", trước tiên, nó sử dụng string()hàm để biến đổi chúng thành kiểu chuỗi, hơn là nhận được kết quả boolean.

Có hai quy tắc quan trọng về string():

  1. Các string()chức năng chuyển đổi một nút-thiết lập để một chuỗi bằng cách trả lại chuỗi giá trị của nút đầu tiên trong nút-set, mà trong một số trường hợp có thể mang lại kết quả bất ngờ.

    text()là đường dẫn tương đối trả về một tập hợp nút chứa tất cả nút văn bản của nút hiện tại (nút bối cảnh), như ["Data"]. Khi được đánh giá bởi string(["Data"]), nó sẽ trả về nút đầu tiên của tập hợp nút, do đó bạn chỉ nhận được "Dữ liệu" khi chỉ có một nút văn bản trong tập hợp nút.

  2. Nếu bạn muốn string()hàm ghép nối tất cả văn bản con, thì bạn phải truyền một nút thay vì tập nút.

    Ví dụ: chúng tôi nhận được một tập hợp nút ['a', 'b'], bạn có thể chuyển qua nút cha đó string(parent), điều này sẽ trả về 'ab'và vì lý do string(.)trong trường hợp của bạn sẽ trả về một chuỗi nối "Data".

Cả hai cách sẽ nhận được cùng một kết quả chỉ khi có một nút văn bản.

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.