J'ai une chaîne XML comme celle-ci
<resp><status>good</status><msg>hi</msg></resp>
Je suis cette aide
moyen le plus simple d'interroger XML en 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);
}
Je veux obtenir la valeur du nœud msg mais j'ai une 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
Je ne vais pas utiliser de bibliothèque externe pour cette tâche simple. veuillez me guider comment obtenir les valeurs des autres nœuds. Merci
Vous ne pouvez pas réutiliser la même InputSource
pour plusieurs appels evaluate()
car elle est automatiquement fermée. Vous obtenez donc le Stream closed
IO exception. Essayez ceci
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);
MODIFIER:
Une meilleure approche serait d'utiliser une DocumentBuilderFactory
pour analyser votre XML et créer d'abord une Document
(en utilisant les API DOM de JAXP) qui peut ensuite être réutilisée dans plusieurs évaluations XPath .
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);
solution de Ravi peut également s'exprimer comme suit:
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));
Document doc = (Document) xpath.evaluate("/", source, XPathConstants.NODE);
String status = xpath.evaluate("/resp/status", doc);
String msg = xpath.evaluate("/resp/msg", doc);
System.out.println("status=" + status);
System.out.println("Message=" + msg);
Tu peux essayer jcabi-xml
, qui effectue des manipulations DOM en arrière-plan:
import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
XML xml = new XMLDocument("<resp>...</resp>");
String status = xml.xpath("/resp/status/text()").get(0);