Reputation: 3
I am using java XPathFactory to get values from a simple xml file:
<Obama>
<coolnessId>0</coolnessId>
<cars>0</cars>
<cars>1</cars>
<cars>2</cars>
</Obama>
With the xpression //Obama/coolnessId | //Obama/cars
the result is:
0
0
1
2
From this result, I cannot distinguish between what is the coolnessId and what is the car id. I would need something like:
CoolnessId: 0
CarId: 0
CarId: 1
CarId: 2
With concat('c_id: ', //Obama/coolnessId,' car_id: ',//Obama/cars)
I am close to the solution, but concat cannot be used for a list of values.
Unfortunately, I cannot use string-join, because it seems not be known in my xpath library. And I cannot manipulate the given xml.
What other tricks can I use to get a list of values with something like an alias?
Upvotes: 0
Views: 424
Reputation: 163342
Assuming you ask for the result of the evaluation as a NODELIST, your XPath expression actually returns a sequence of four element nodes, not a sequence of four strings as you suggest. If your input uses the DOM tree model, these will be returned in the form of a DOM NodeList. You can process the Node objects in this NodeList to get the names of the nodes as well as their string values.
If you switch to an XPath 3.1 engine such as Saxon, you can get the result directly as a single string using the XPath expression:
string-join((//Obama/coolnessId | //Obama/cars) ! (name() || ': ' || string()), '\n')
To invoke XPath expressions in Saxon you can use either the JAXP API (javax.xml.xpath) or Saxon's s9api interface: I would recommend s9api because it understands the richer type system of XPath 2.0 and beyond.
Upvotes: 1
Reputation: 7286
If you select the elements rather than their text content you'll have some context:
public static void main(String[] args) throws Exception {
String xml =
"<Obama>" +
" <coolnessId>0</coolnessId>" +
" <cars>0</cars>" +
" <cars>1</cars>" +
" <cars>2</cars>" +
"</Obama>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//Obama/cars | //Obama/coolnessId");
NodeList result = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < result.getLength(); i++) {
Element item = (Element) result.item(i);
System.out.println(item.getTagName() + ": " + item.getTextContent());
}
}
Upvotes: 2