I want to create a class to parse XML.
Here is my code :
public class ParserXML {
private String Flux;
private ArrayList<String> EvaluateExpr = new ArrayList<String>();
private ArrayList<String> Result = new ArrayList<String>();
public ParserXML(String url, ArrayList<String> exp) {
this.Flux = url;
this.EvaluateExpr = exp;
this.loadXmlFlux();
}
private void loadXmlFlux() {
HttpClient httpclient = null;
try {
httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(this.Flux);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpget, responseHandler);
InputSource docXml = new InputSource(new StringReader(responseBody));
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
ArrayList<String> result = new ArrayList<String>();
/*
* Looping on all expression to evaluate
*/
for (String i : this.EvaluateExpr) {
try {
result.add(xpath.evaluate(i, docXml));
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
this.Result = result;
} catch (HttpResponseException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
finally{
if(httpclient!=null) {
httpclient.getConnectionManager().shutdown();
}
}
}
public ArrayList<String> getResult() {
return this.Result;
}
}
This class working fine when I’ve only one expression to evaluate.
But if I want to evaluate 2 expression on the XML stream I’ve error.
java.io.IOException: Stream closed
at java.io.StringReader.ensureOpen(Unknown Source)
at java.io.StringReader.read(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at Common.ParserXML.loadXmlFlux(ParserXML.java:56)
at Common.ParserXML.(ParserXML.java:29)
at Domaine.Ahref.loadReferringDomains(Ahref.java:46)
at Domaine.Ahref.(Ahref.java:19)
at MainApp.checkAhrefs(MainApp.java:199)
at MainApp.main(MainApp.java:67)
————— linked to ——————
javax.xml.xpath.XPathExpressionException
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
at Common.ParserXML.loadXmlFlux(ParserXML.java:56)
at Common.ParserXML.(ParserXML.java:29)
at Domaine.Ahref.loadReferringDomains(Ahref.java:46)
at Domaine.Ahref.(Ahref.java:19)
at MainApp.checkAhrefs(MainApp.java:199)
at MainApp.main(MainApp.java:67)
Caused by: java.io.IOException: Stream closed
at java.io.StringReader.ensureOpen(Unknown Source)
at java.io.StringReader.read(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.arrangeCapacity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipString(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
I don’t understand why I can’t use again the “xpath.evaluate(i, docXml)” in the loop.
Thanks
You’re using the same
InputSourcetwice – and after thatInputSourcehas read the input once, the input is exhausted.The simplest approach is probably to create a new
InputSourcefor each iteration, with a newStringReadereach time. Basically move this line:into the loop.
Alternatively, I’m sure there must be a way of evaluating an XPath expression against a parsed DOM representation (e.g.
Document) but I haven’t done enough Java XML work recently to know the relevant magic incantations. That would avoid having to reparse the XML for each expression though, which would obviously be nice.