Извлечь значение атрибута узла через XPath

182

Как я могу извлечь значение атрибута node через 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
Теги:
xpath

6 ответов

242
Лучший ответ
//Parent[@id='1']/Children/child/@name 

Ваш оригинальный child[@name] означает элемент child, который имеет атрибут name. Вы хотите child/@name.

  • 14
    Я согласен, вопрос был, как получить значение атрибута
  • 5
    Что делать, если я хотел бы извлечь только значение / описание / данные, присутствующие между тегами ....
102

Чтобы получить только значение (без имен атрибутов), используйте string():

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

  • 1
    С xqilla нужно было вызвать xs:string . Интересно, почему.
  • 1
    @krlmlr Вероятно, xs - это префикс пространства имен для функций XPath. Поэтому они не перепутаны с другими.
Показать ещё 1 комментарий
5

Как было сказано выше:

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

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

Однако, если вы вообще игнорируете Parent node и используете:

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

Атрибуты не могут быть сериализованы, поэтому вы не можете вернуть их в результате поиска xml. Что вам нужно сделать, так это получить данные из атрибута с помощью функции data().

  • 5
    не работает с xmllint
  • 0
    не работает с .net
3
//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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню