Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse XML Simple String using Java XPath

Tags:

java

xml

xpath

I have XML String like this

<resp><status>good</status><msg>hi</msg></resp> 

I follow this help

Simplest way to query XML in Java

MyCode:

public static void main(String args[]) {      String xml = "<resp><status>good</status><msg>hi</msg></resp>";      XPathFactory xpathFactory = XPathFactory.newInstance();     XPath xpath = xpathFactory.newXPath();      InputSource source = new InputSource(new StringReader(xml));      String status = "";     String msg = "";     try {         status = (String) xpath.evaluate("/resp/status", source,XPathConstants.STRING);         msg = (String) xpath.evaluate("/resp/msg", source,XPathConstants.STRING);     } catch (Exception e) {         e.printStackTrace();     }      System.out.println("status=" + status);     System.out.println("Message=" + msg);   } 

I want to get msg node value but i got exception

java.io.IOException: Stream closed at java.io.StringReader.ensureOpen(StringReader.java:39) at java.io.StringReader.read(StringReader.java:73) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1619) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1657) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:193) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:225) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:468) at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:515) at Parsing.main(Parsing.java:25)--------------- linked to ------------------ javax.xml.xpath.XPathExpressionException at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:475) at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:515) at Parsing.main(Parsing.java:25) Caused by: java.io.IOException: Stream closed at java.io.StringReader.ensureOpen(StringReader.java:39) at java.io.StringReader.read(StringReader.java:73) at     com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(XMLEntityScanner.java:1742) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(XMLEntityScanner.java:1619) at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(XMLEntityScanner.java:1657) at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:193) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:107) at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:225) at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:283) at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(XPathImpl.java:468) ... 2 more 

I am not going to use some external library for this simple task. please guide me how to get other node's values. Thanks

like image 683
Waqas Ali Avatar asked May 23 '13 11:05

Waqas Ali


People also ask

What is Java XPath?

XPath is a syntax used to describe parts of an XML document. With XPath, you can refer to the first element, any attribute of the elements, all specific elements that contain the some text, and many other variations.


1 Answers

You can't reuse the same InputSource for multiple evaluate() invocations because it's automatically closed. Hence you're getting the Stream closed IO exception. Try this

InputSource source1 = new InputSource(new StringReader(xml)); InputSource source2 = new InputSource(new StringReader(xml));  String msg = xpath.evaluate("/resp/msg", source); String status = xpath.evaluate("/resp/status", source2);  System.out.println("msg=" + msg + ";" + "status=" + status); 

EDIT:
A better approach would be to use a DocumentBuilderFactory to parse your XML and build a Document first (using JAXP's DOM APIs) which can then be reused across several XPath evaluations.

String xml = "<resp><status>good</status><msg>hi</msg></resp>";  InputSource source = new InputSource(new StringReader(xml));  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(source);  XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath();  String msg = xpath.evaluate("/resp/msg", document); String status = xpath.evaluate("/resp/status", document);  System.out.println("msg=" + msg + ";" + "status=" + status); 
like image 62
Ravi K Thapliyal Avatar answered Sep 22 '22 02:09

Ravi K Thapliyal