私はこのようなXML文字列を持っています
<resp><status>good</status><msg>hi</msg></resp>
このヘルプに従います
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);
}
メッセージノード値を取得したいが、例外が発生した
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
この単純なタスクに外部ライブラリを使用するつもりはありません。他のノードの値を取得する方法を教えてください。ありがとう
同じInputSource
を複数のevaluate()
呼び出しに再利用することはできません。自動的に閉じられるためです。したがって、Stream closed
IO exception。これを試してください
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);
編集:
より良いアプローチは、DocumentBuilderFactory
を使用してXMLを解析し、最初に(JAXPのDOM APIを使用して)Document
を構築し、それを複数の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);
ラビの解 は次のようにも表現できます:
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);
あなたが試すことができます - jcabi-xml
、これはDOM操作を舞台裏で行います。
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);