Ответ 1
//Parent[@id='1']/Children/child/@name
Ваш оригинальный child[@name]
означает элемент child
, который имеет атрибут name
. Вы хотите child/@name
.
Как я могу извлечь значение атрибута 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
//Parent[@id='1']/Children/child/@name
Ваш оригинальный child[@name]
означает элемент child
, который имеет атрибут name
. Вы хотите child/@name
.
Чтобы получить только значение (без имен атрибутов), используйте string()
:
string(//Parent[@id='1']/Children/child/@name )
Функция fn: string() вернет значение своего аргумента в виде xs:string
. Если его аргумент является атрибутом, он возвращает значение атрибута в виде xs:string
.
Как ответили выше:
//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"
Вы должны использовать //Parent[@id='1']/Children/child/data(@name)
Атрибуты не могут быть сериализованы, поэтому вы не можете вернуть их в результате поиска xml. Что вам нужно сделать, так это получить данные из атрибута с помощью функции data().
//Parent/Children[@ Attribute='value']/@Attribute
Это тот случай, который может использоваться, когда элемент имеет атрибут 2, и мы можем получить один атрибут с помощью другого.
@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
для всех XML с пространством имен используйте local-name()
//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name