How can I extract the value of an attribute node via XPath?
A sample XML file is:
<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>
So far I have this XPath string:
//Parent[@id='1']/Children/child[@name]
It returns only child
elements, but I would like to have the value of the name
attribute.
For my sample XML file, here's what I'd like the output to be:
Child_2
Child_4
Child_1
Child_3
//Parent[@id='1']/Children/child/@name
Your original child[@name]
means an element child
which has an attribute name
. You want child/@name
.
To get just the value (without attribute names), use string()
:
string(//Parent[@id='1']/Children/child/@name)
The fn:string() fucntion will return the value of its argument as xs:string
. In case its argument is an attribute, it will therefore return the attribute's value as xs:string
.
You should use //Parent[@id='1']/Children/child/data(@name)
The attributes can not be serialized so you can't return them in an xml looking result. What you need to do is obtain the data from the attribute using data() function.
As answered above:
//Parent[@id='1']/Children/child/@name
will only output the name
attribute of the 4 child
nodes belonging to the Parent
specified by its predicate [@id=1]
. You'll then need to change the predicate to [@id=2]
to get the set of child
nodes for the next Parent
.
However, if you ignore the Parent
node altogether and use:
//child/@name
you can select name
attribute of all child
nodes in one go.
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/Children[@ Attribute='value']/@Attribute
This is the case which can be used where element is having 2 attribute and we can get the one attribute with the help of another one.
@ryenus, You need to loop through the result. This is how I'd do it in 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
for all xml with namespace use local-name()
//*[local-name()='Parent'][@id='1']/*[local-name()='Children']/*[local-name()='child']/@name