XPath - retrieve multiple values from different paths based on same condition
13,946
Solution 1
This would be the correct path:
/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']
To retrieve a list of nodes, you need to use the version of xPath.evaluate() that takes a returnType parameter:
InputSource document = new InputSource(new FileInputStream("user1.xml"));
String xpath = "/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']";
NodeSet result = (NodeSet)xPath.evaluate(xpath, document, XPathConstants.NODESET);
for(int index = 0; index < result.getLength(); index ++) {
Node node = result.item(index);
String name = node.getNodeValue();
}
Solution 2
/root/entry[value[@name="ID" and .=11]]/value[@name="NAME"]
or
/root/entry/value[@name="ID" and .=11]/../value[@name="NAME"]
or
/descendant::entry[value=11 and value/@name="ID"]/value[@name="NAME"]
or
//value[.=11]/@name[.="ID"]/ancestor::entry/value[@name="NAME"]
or many other variations
Solution 3
Use:
/*/*[*[@name='ID'] = 11]/*[@name='NAME']
XSLT - based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="/*/*[*[@name='ID'] = 11]/*[@name='NAME']"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<root>
<entry id="1">
<value name="ID">11</value>
<value name="ENABLE">0</value>
<value name="NAME">USER1</value>
</entry>
<entry id="2">
<value name="ID">11</value>
<value name="ENABLE">0</value>
<value name="NAME">USER2</value>
</entry>
<entry id="3">
<value name="ID">12</value>
<value name="ENABLE">0</value>
<value name="NAME">USER1</value>
</entry>
</root>
the XPath expression is evaluated and the result of this evaluation (all selected nodes) is copied to the output:
<value name="NAME">USER1</value>
<value name="NAME">USER2</value>
Comments
-
Abi almost 2 years
This is my XML
<root> <entry id="1"> <value name="ID">11</value> <value name="ENABLE">0</value> <value name="NAME">USER1</value> </entry> <entry id="2"> <value name="ID">11</value> <value name="ENABLE">0</value> <value name="NAME">USER2</value> </entry> <entry id="3"> <value name="ID">12</value> <value name="ENABLE">0</value> <value name="NAME">USER1</value> </entry> </root>
I need an XPath query to retrieve all the names whose
id
is 11.I tried:
String xpath = "/root/entry/value[@name=ID/text()='11']/value[@name='NAME']"; String xpath = "/root/entry/value[@name=ID/text()='11']/NAME";
Can someone tell me what is wrong in my query?
EDIT:
Expected Output:
USER1 USER2
both these have ID = 11
-
Abi over 11 yearsNope,I am getting 11 as the output
-
jeewiya over 11 yearsi have missing NAME part,check it now
-
Abi over 11 yearsi am getting only one user value returned
-
Abi over 11 yearsfirst option - infinite loop. second option - returns only one user USER1
-
Abi over 11 yearsfourth option also returns only one value
-
JLRishe over 11 years@Abi Sorry, I had an extra slash. Please try it now.
-
Abi over 11 yearsThanks, this is working but is XSL the only way to go about it? Cannot be done using normal XPath?Because when I tried using that Xpath in my class it returned only user1
-
JLRishe over 11 years@Abi Both Dimitre's example and mine should find USER1 and USER2. If you're only getting one value, it's the way you're applying the XPath that's wrong. Please show us your actual code.
-
Abi over 11 years@JLRishe - yes that may be the mistake, code is String xpath = "/root/entry[value[@name = 'ID'] = 11]/value[@name = 'NAME']"; String result = xPath.evaluate(xpath, new InputSource(new FileInputStream("user1.xml")));
-
Dimitre Novatchev over 11 years@abi, the result from
evaluate()
most probably is Object -- and needs to be cast to a list of nodes. Your mistake is that you are assigning it to a String. I don't know what XPath API you are using (the PL seems to be Java) -- please, read well the documentation and review any available code examples, so that you can correct your current code. -
Abi over 11 yearsMYBAD!!! didnt realize i had messed up in the reading the result part. Thanks alot for all your answers