Ekstrak nilai node atribut melalui XPath

270

Bagaimana saya bisa mengekstrak nilai simpul atribut melalui XPath?

Contoh file XML adalah:

<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>

Sejauh ini saya memiliki string XPath ini:

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

Hanya mengembalikan childelemen, tapi saya ingin memiliki nilai nameatribut.

Untuk file XML sampel saya, inilah yang saya inginkan dari hasilnya:

Child_2
Child_4
Child_1
Child_3
Rehman
sumber
Kemungkinan rangkap dari atribut Mendapatkan menggunakan XPath
tripleee

Jawaban:

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

Sumber asli Anda child[@name]berarti elemen childyang memiliki atribut name. Kamu ingin child/@name.

pemilik
sumber
14
Saya setuju, pertanyaannya adalah bagaimana cara mendapatkan nilai atribut
Vladtn
5
Bagaimana jika saya ingin mengekstrak hanya nilai / deskripsi / data yang ada di antara tag ....
Dinu Duke
147

Untuk mendapatkan nilai saja (tanpa nama atribut), gunakan string():

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

The fn: string () fucntion akan mengembalikan nilai dari argumen sebagai xs:string. Jika argumennya adalah atribut, maka itu akan mengembalikan nilai atribut sebagai xs:string.

acdcjunior
sumber
1
Dengan xqillaitu perlu menelepon xs:string. Kenapa ya.
krlmlr
1
@ krlmlr Mungkin xsadalah awalan namespace untuk fungsi XPath. Jadi mereka tidak tercampur dengan orang lain.
acdcjunior
4
LOL. Ini adalah satu-satunya jawaban yang benar-benar menjawab pertanyaan itu. +1
james.garriss
3
Ini hanya akan memberikan hit pertama di xmllint
crazyduck
1
Bagaimana jika saya memiliki daftar atribut dan saya perlu nilainya? string () tampaknya mengembalikan nilai pertama saja.
damluar
9

Kamu harus menggunakan //Parent[@id='1']/Children/child/data(@name)

Atribut tidak dapat diserialisasi sehingga Anda tidak dapat mengembalikannya dalam hasil pencarian xml. Yang perlu Anda lakukan adalah mendapatkan data dari atribut menggunakan fungsi data ().

Natalia Maciejowska
sumber
9

Seperti yang dijawab di atas:

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

hanya akan menampilkan nameatribut 4 childnode milik yang Parentditentukan oleh predikatnya [@id=1]. Anda kemudian harus mengubah predikat [@id=2]untuk mendapatkan set childnode untuk selanjutnya Parent.

Namun, jika Anda mengabaikan Parentsimpul sama sekali dan menggunakan:

//child/@name

Anda dapat memilih nameatribut semua childnode dalam sekali jalan.

name="Child_2"
name="Child_4"
name="Child_1"
name="Child_3"
name="Child_1"
name="Child_2"
name="Child_4"
name="Child_3"
Vinod Srivastav
sumber
6
//Parent/Children[@  Attribute='value']/@Attribute

Ini adalah kasus yang dapat digunakan di mana elemen memiliki 2 atribut dan kita bisa mendapatkan satu atribut dengan bantuan yang lain.

Akshay Dubey
sumber
3

@ryenus, Anda harus mengulang hasilnya. Ini adalah bagaimana saya melakukannya dalam 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
NickC
sumber
3

untuk semua xml dengan namespace gunakan local-name ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
Ed Bangga
sumber