Trích xuất giá trị của nút thuộc tính thông qua XPath


269

Làm cách nào để trích xuất giá trị của nút thuộc tính qua XPath?

Một tệp XML mẫu là:

<parents name='Parents'>
  <Parent id='1' name='Parent_1'>
    <Children name='Children'>
      <child name='Child_2' id='2'>child2_Parent_1</child>
      <child name='Child_4' id='4'>child4_Parent_1</child>
      <child name='Child_1' id='3'>child1_Parent_1</child>
      <child name='Child_3' id='1'>child3_Parent_1</child>
    </Children>
  </Parent>
  <Parent id='2' name='Parent_2'>
    <Children name='Children'>
      <child name='Child_1' id='8'>child1_parent2</child>
      <child name='Child_2' id='7'>child2_parent2</child>
      <child name='Child_4' id='6'>child4_parent2</child>
      <child name='Child_3' id='5'>child3_parent2</child>
    </Children>
  </Parent>
</parents>

Cho đến nay tôi có chuỗi XPath này:

//Parent[@id='1']/Children/child[@name]  

Nó chỉ trả về childcác phần tử, nhưng tôi muốn có giá trị của namethuộc tính.

Đối với tệp XML mẫu của tôi, đây là những gì tôi muốn đầu ra là:

Child_2
Child_4
Child_1
Child_3

Bản sao có thể có của thuộc tính Bắt bằng XPath
tripleee

Câu trả lời:


349
//Parent[@id='1']/Children/child/@name 

Bản gốc của bạn child[@name]có nghĩa là một yếu tố childcó thuộc tính name. Bạn muốn child/@name.


14
Tôi đồng ý, câu hỏi là làm thế nào để có được giá trị của thuộc tính
Vladtn

5
Điều gì sẽ xảy ra nếu tôi chỉ muốn trích xuất giá trị / mô tả / dữ liệu ở giữa các thẻ ....
Dinu Duke

146

Để chỉ nhận giá trị (không có tên thuộc tính), hãy sử dụng string():

string(//Parent[@id='1']/Children/child/@name)

Các fn: string () fucntion sẽ trả về giá trị của các đối số của nó như là xs:string. Trong trường hợp đối số của nó là một thuộc tính, do đó nó sẽ trả về giá trị của thuộc tính là xs:string.


1
Với xqillanó là cần thiết để gọi xs:string. Tôi tự hỏi tại sao.
krlmlr

1
@krlmlr Có lẽ xslà tiền tố không gian tên cho các hàm XPath. Vì vậy, họ không trộn lẫn với những người khác.
acdcjunior

4
CƯỜI LỚN. Đây là câu trả lời duy nhất thực sự trả lời câu hỏi. +1
james.garriss

3
Điều này sẽ chỉ cung cấp lần truy cập đầu tiên trong xmllint
crazyduck

1
Nếu tôi có một danh sách các thuộc tính và tôi cần các giá trị của chúng thì sao? chuỗi () dường như chỉ trả về giá trị đầu tiên.
damluar

8

Bạn nên sử dụng //Parent[@id='1']/Children/child/data(@name)

Các thuộc tính không thể được tuần tự hóa để bạn không thể trả lại chúng trong kết quả tìm kiếm xml. Những gì bạn cần làm là lấy dữ liệu từ thuộc tính bằng hàm data ().


7

Như đã trả lời ở trên:

//Parent[@id='1']/Children/child/@name 

sẽ chỉ xuất ra namethuộc tính của 4 childnút thuộc về Parentvị ngữ được chỉ định bởi vị từ của nó [@id=1]. Sau đó, bạn sẽ cần thay đổi vị từ [@id=2]để lấy tập hợp các childnút cho lần tiếp theo Parent.

Tuy nhiên, nếu bạn bỏ qua Parentnút hoàn toàn và sử dụng:

//child/@name

bạn có thể chọn namethuộc tính của tất cả childcác nút trong một lần.

name="Child_2"
name="Child_4"
name="Child_1"
name="Child_3"
name="Child_1"
name="Child_2"
name="Child_4"
name="Child_3"

5
//Parent/Children[@  Attribute='value']/@Attribute

Đây là trường hợp có thể được sử dụng khi phần tử đang có 2 thuộc tính và chúng ta có thể có được một thuộc tính với sự trợ giúp của một thuộc tính khác.


1

@ryenus, Bạn cần lặp qua kết quả. Đây là cách tôi làm trong vbscript;

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.setProperty "SelectionLanguage", "XPath"
xmlDoc.load("kids.xml")

'Remove the id=1 attribute on Parent to return all child names for all Parent nodes
For Each c In xmlDoc.selectNodes ("//Parent[@id='1']/Children/child/@name")
    Wscript.Echo c.text
Next

1

đối với tất cả xml có không gian tên, hãy sử dụng tên cục bộ ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
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.