2012-07-31 50 views
51

Tôi đang gặp sự cố khi hiểu sự khác biệt giữa text()node(). Từ những gì tôi hiểu, text() sẽ nằm ở giữa các thẻ <item>apple</item>apple trong trường hợp này. Nút này sẽ là bất kỳ nút nào thực sự là, có thể là mụcXPath - Sự khác biệt giữa nút() và văn bản()

Nhưng sau đó tôi đã được giao một số công việc yêu cầu "Chọn văn bản của tất cả các mục trong sản phẩm" và một câu hỏi riêng biệt hỏi "Chọn tất cả các nút quản lý trong tất cả các phòng ban"

thế nào là sản phẩm giả nhìn text() như trái ngược với node()

Snippet của XML:

<produce> 
<item>apple</item> 
<item>banana</item> 
<item>pepper</item> 
</produce> 

<department> 
<phone>123-456-7891</phone> 
<manager>John</manager> 
</department> 

Tất nhiên, có nhiều phòng ban và nhiều người quản lý hơn, nhưng đây chỉ là một đoạn mã.

Mọi trợ giúp sẽ được đánh giá cao!

Trả lời

109

text()node()kiểm tra nút, trong thuật ngữ XPath (compare).

Kiểm tra nút hoạt động trên một tập hợp (trên axis, chính xác) của các nút và trả về các nút thuộc một loại nhất định. Khi không có trục nào được đề cập, trục child được giả định theo mặc định.

Có tất cả các loại node tests:

  • node() trận bất kỳ nút (kiểm tra nút cụ thể nhất trong số họ tất cả)
  • text() trận văn bản nút chỉ
  • comment() trận bình luận nodes
  • * khớp với bất kỳ yếu tố nút
  • foo trận đấu bất kỳ nút phần tử tên "foo"
  • processing-instruction() trận hạch PI (họ trông giống như <?name value?>).
  • Lưu ý phụ:* cũng khớp với nút thuộc tính, nhưng chỉ dọc theo trục attribute. @* là viết tắt của attribute::*. Thuộc tính không phải là một phần của trục child, đó là lý do tại sao * bình thường không chọn chúng.

Tài liệu này XML:

<produce> 
    <item>apple</item> 
    <item>banana</item> 
    <item>pepper</item> 
</produce> 

đại diện cho DOM sau (giản thể):

 
root node 
    element node (name="produce") 
     text node (value="\n ") 
     element node (name="item") 
     text node (value="apple") 
     text node (value="\n ") 
     element node (name="item") 
     text node (value="banana") 
     text node (value="\n ") 
     element node (name="item") 
     text node (value="pepper") 
     text node (value="\n") 

Vì vậy, với XPath:

  • / chọn nút gốc
  • /produce chọn phần tử con của nút gốc nếu tên đó có tên "produce" (Đây được gọi là thành phần tài liệu ; nó đại diện cho bản thân tài liệu. yếu tố tài liệu và nút gốc thường bị nhầm lẫn, nhưng họ không phải là điều tương tự.)
  • /produce/node() Selects bất kỳ loại nút con dưới /produce/ (tức là tất cả 7 trẻ em)
  • /produce/text() chọn 4 (!) khoảng trắng chỉ các nút văn bản
  • /produce/item[1] chọn phần tử con đầu tiên tên là "item"
  • /produce/item[1]/text() Selects tất cả nút văn bản con (chỉ có một - "quả táo" - trong trường hợp này)

Và cứ tiếp tục như vậy.

Vì vậy, câu hỏi của bạn

  • "Chọn văn bản của tất cả các mặt hàng dưới sản phẩm"/produce/item/text() (3 nút chọn)
  • "Chọn tất cả các nút quản lý trong tất cả các phòng ban"//department/manager (1 nút được chọn)

Ghi chú

  • Mặc định trục trong XPath là trục child. Bạn có thể thay đổi trục bằng cách đặt trước tên trục khác. Ví dụ: //item/ancestor::produce
  • Các nút phần tử có giá trị văn bản. Khi bạn đánh giá một nút phần tử, nội dung văn bản của nó sẽ được trả về. Trong trường hợp của ví dụ này, /produce/item[1]/text()string(/produce/item[1]) sẽ giống nhau.
  • Cũng xem this answer nơi tôi phác thảo các phần riêng lẻ của biểu thức XPath bằng đồ thị.
+2

@Xeoncross Cảm ơn bạn. :) – Tomalak

+5

Đó là một câu trả lời tuyệt vời, nhưng đối với hồ sơ, có một vài điểm không chính xác. (a) Ý nghĩa của phép thử nút '" * "' phụ thuộc vào trục: với hầu hết các trục, nó chọn các nút phần tử, nhưng với trục thuộc tính nó chọn các thuộc tính, và với trục không gian tên nó chọn các không gian tên. (b) '@ *' và '@ foo' không phải là kiểm tra nút, nhưng các bước trục, bao gồm hai phần: một trục (' @ ', viết tắt của' attribute :: ') và một nút kiểm tra ('*' hoặc 'foo'). –

+1

@MichaelKay Cảm ơn bạn đã làm rõ. Tôi sẽ sửa đổi các bit gây hiểu lầm.Tuy nhiên, các trục nằm ngoài phạm vi của câu hỏi này, nhưng thật khó để tránh đề cập đến chúng khi bạn đang nói về XPath. – Tomalak

0

Chọn văn bản của tất cả các mặt hàng dưới sản phẩm:

//produce/item/text() 

Chọn tất cả các nút quản lý trong tất cả các phòng ban:

//department/* 
Các vấn đề liên quan