Reputation: 346
Example xml:
<root>
<ns1:agent ns2:about="a3">
<ns2:name xml:lang="en">Helen</ns2:name>
<ns2:age>26</ns2:age>
</ns1:agent>
<ns1:agent ns2:about="a1">
<ns2:name xml:lang="en">John</ns2:name>
<ns2:age>26</ns2:age>
</ns1:agent>
<ns1:agent ns2:about="a2">
<ns2:name xml:lang="en">Mike</ns2:name>
<ns2:age>30</ns2:age>
</ns1:agent>
...
<!-- More ns1:agent nodes -->
...
<ns3:person ns2:id="a1"/>
<ns3:person ns2:id="a2"/>
<ns3:person ns2:id="a3"/>
...
<!-- More ns3:person nodes -->
...
</root>
So how to get the text value of the agent/name element based on its about attribute starting from person element, using XPath?
Edit: XPath expression will be used in a loop, for each ns3:person node, so I don't know the specific id attribute value beforehand.
Upvotes: 1
Views: 156
Reputation: 111491
Assuming you've properly declared namespace prefixes ns1
, ns2
, and ns3
, this XPath,
//ns3:person[@ns2:id = "a1"]/preceding-sibling::ns1:agent[1]/ns2:name
will select the name of the agent immediately preceding the identified person.
If you need help declaring the XML namespace prefixes, see How does XPath deal with XML namespaces?
Update based on OP's comment:
In my original xml document, the agent node is not immediately preceding the person node. I will be running the expression in a loop, for each person node. Sorry for the confusion, I have edited the example and the question so it is more clear what I need.
And in the edited question:
Edit: XPath expression will be used in a loop, for each ns3:person node, so I don't know the specific id attribute value beforehand.
So in your loop simply bind a variable, say $id
, to the current ns3:person/@n2:id
and then test it in the XPath:
//ns1:agent[@ns2:about = $id]/ns2:name
See also How to pass variable parameter into XPath expression?
Upvotes: 1
Reputation: 24930
If I understand your question correctly, you are looking for an xpath expression like this:
//ns1:agent[@ns2:about=//ns3:person/@ns2:id]/ns2:name
To test it, I would change your ns3:persons
nodes in your sample xml from
<ns3:person ns2:id="a1"/>
<ns3:person ns2:id="a2"/>
<ns3:person ns2:id="a3"/>
to
<ns3:person ns2:id="a7"/>
<ns3:person ns2:id="a2"/>
<ns3:person ns2:id="a9"/>
so that only one random ns1:agent
corresponds to one random ns3:person
. If you do that, that xpath expression would select Mike
as the target name.
Upvotes: 1