Витяг значення вузла атрибута через XPath


269

Як я можу отримати значення вузла атрибута через XPath?

Зразок XML-файлу:

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

Поки що у мене є ця рядок XPath:

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

Він повертає лише childелементи, але я хотів би мати значення nameатрибута.

У моєму зразковому XML-файлі ось що я хотів би бути результатом:

Child_2
Child_4
Child_1
Child_3

Відповіді:


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

Ваш оригінал child[@name]означає елемент, childякий має атрибут name. Ти хочеш child/@name.


14
Я згоден, питання полягало у тому, як отримати значення атрибута
Владтн

5
Що робити, якщо я хотів би отримати лише значення / опис / дані між тегами ....
Dinu Duke

146

Щоб отримати лише значення (без імен атрибутів), використовуйте string():

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

Виноска: рядок () fucntion повертає значення аргументу як xs:string. Якщо його аргумент є атрибутом, він поверне значення атрибута як xs:string.


1
З xqillaним треба було дзвонитиxs:string . Цікаво, чому.
krlmlr

1
@krlmlr Можливо, xsце префікс простору імен для функцій XPath. Тому вони не змішуються з іншими.
acdcjunior

4
ЛОЛ. Це єдина відповідь, яка насправді відповідає на питання. +1
james.garriss

3
Це забезпечить лише перший хіт у xmllint
crazyduck

1
Що робити, якщо у мене є список атрибутів і мені потрібні їх значення? здається, що string () повертає лише перше значення.
дамлюар

8

Ви повинні використовувати //Parent[@id='1']/Children/child/data(@name)

Атрибути не можна серіалізувати, тому ви не можете повернути їх у результатах пошуку у форматі XML. Що потрібно зробити, це отримати дані з атрибута за допомогою функції data ().


7

Як відповів вище:

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

виведе лише nameатрибут 4-х childвузлів, що належать Parentвказаному його присудком [@id=1]. Потім вам потрібно буде змінити присудок, [@id=2]щоб отримати набір childвузлів для наступного Parent.

Однак якщо ви Parentвзагалі ігноруєте вузол і використовуєте:

//child/@name

ви можете вибрати nameатрибут усіх childвузлів за один раз.

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

Це той випадок, який можна використовувати, коли елемент має 2 атрибути, і ми можемо отримати один атрибут за допомогою іншого.


1

@ryenus, Вам потрібно провести результат через результат. Ось як я це зробив би в 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

для всіх xml з простором імен використовуйте local-name ()

//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.