I get this exception while parsing XML, but not always. After error When I try again immediately, it works. But why I get sometomes this error ?
Here is my code and error too.
StringEntity entity = new StringEntity(author, "UTF-8");
DefaultHttpClient httpClient = new DefaultHttpClient();
SharedPreferences logIn = context.getSharedPreferences("Data", Context.MODE_PRIVATE);
HttpPost httppost = new HttpPost(logIn.getString("Url", ""));
httppost.setEntity(entity);
httppost.addHeader("Accept", "text/xml");
httppost.addHeader("Content-Type", "text/xml");
HttpResponse response = httpClient.execute(httppost);
HttpEntity r_entity = response.getEntity();
xmlRecords = EntityUtils.toString(r_entity);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList workItemsNode = doc.getElementsByTagName("Items");
for (int i = 0; i < workItemsNode.getLength(); i++) {
//Some Code here
}
Exception
org.xml.sax.SAXParseException: Unexpected end of document
at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:125)
at com.mobile.syrinx.services.SynchroniseWorkItemsService.FillLists(SynchroniseWorkItemsService.java:101)
at com.mobile.syrinx.services.SynchroniseWorkItemsService.doInBackground(SynchroniseWorkItemsService.java:65)
at com.mobile.syrinx.services.SynchroniseWorkItemsService.doInBackground(SynchroniseWorkItemsService.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:252)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574)
at java.lang.Thread.run(Thread.java:1020)
1) Verify that you're receiving valid XML. If you're consuming XML provided to you from a webservice, well who knows what you're getting. Invalid XML can cause problems for a lot of these parsers. The fac that this only occurs sometimes makes me think that is most likely the culprit.
The DocumentBuilder documentation is here:
http://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/DocumentBuilder.html#parse(org.xml.sax.InputSource)
You can see that the SAX exception is thrown when there is an error parsing the xml, this implies that the xml is invalid somehow. The exception should be caught and handled acordingly.
2) Are the files you are parsing originating on different OS's than the one you're acting on? This has caused problems for me in the past, where a windows file caused errors to parsers on linux systems. This shouldn't be the problem here I don't think, but it is possible.
Related
I am new to android programming.My requirement is to invoke the web services.I successfully got the response from web services.how to parse the response in android.Give me solution.
This is the code for getting response:
HttpResponse response = httpclient.execute(httppost);
String str=response.getStatusLine().toString();
System.out.println("========URL STATUS========"+str);
HttpEntity r_entity = response.getEntity();
if( r_entity != null ) {
result = new byte[(int) r_entity.getContentLength()];
if(r_entity.isStreaming()) {
is = new DataInputStream(r_entity.getContent());
is.readFully(result);
}
}
httpclient.getConnectionManager().shutdown();
String responsedata= (new String(result).toString());
The below sample is for dom parser.
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
StringReader sr=new StringReader(result.toString());
is.setCharacterStream(sr);
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("your root tag");
//get your other tag elements.
http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/. Example of dom parser.
http://www.mkyong.com/java/how-to-read-xml-file-in-java-sax-parser/. Example of sax parser.
Dom is w3c based parser. Dom is slower than sax cause it uses tree node and has to be in mmeory. So parsing large data using DOM parser is not recommended.
SAX on the other hand is faster than dom. Recommended for large xml data.
The above links gives you examples of both. Use any of the above parser to parse and get values from the xml tags.
You can try to use SimpleXmlParser. It's a native android class. It's simpler than DOM xml parser.
what you need is simply a android xml parse library. There are plenty of xml parse for android.
official tutorial
there is also a article "comparing methods for xml parsing in android"
I have a problem in DOM parsing Arabic letters, I got weird characters. I've tried changing to different encoding but I couldn't.
the full code is on this link: http://test11.host56.com/parser.java
public Document getDomElement(String xml) {
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
Reader reader = new InputStreamReader(new ByteArrayInputStream(
xml.getBytes("UTF-8")));
InputSource is = new InputSource(reader);
DocumentBuilder db = dbf.newDocumentBuilder();
//InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
return doc;
}
}
my xml file
<?xml version="1.0" encoding="UTF-8"?>
<music>
<song>
<id>1</id>
<title>اهلا وسهلا</title>
<artist>بكم</artist>
<duration>4:47</duration>
<thumb_url>http://wtever.png</thumb_url>
</song>
</music>
You already have the xml as String, so unless that string already contains the odd characters (that is, it has been read in with the wrong encoding), you can avoid encoding madness here by using a StringReader instead; e.g. instead of:
Reader reader = new InputStreamReader(new ByteArrayInputStream(
xml.getBytes("UTF-8")));
use:
Reader reader = new StringReader(xml);
Edit: now that I see more of the code, it seems the encoding issue already happend before the XML is parsed, because that part contains:
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
The javadoc for the EntityUtils.toString says:
The content is converted using the character set from the entity (if any), failing that, "ISO-8859-1" is used.
It seems the server does not send the proper encoding information with the entity, and then the HttpUtils uses a default, which is not UTF-8.
Fix: use the variant that takes an explicit default encoding:
xml = EntityUtils.toString(httpEntity, "utf-8");
Here I assume the server sends UTF-8. If the server uses a different encoding, that one should be set instead of UTF-8. (However as the XML also declares encoding="UTF-8" I thought this is the case.) If the encoding the server uses is not known, then you can only resort to wild guessing and are out of luck, sorry.
If the XML contains Unicode characters such as Arabic or Persian letters, StringReader would make an exception. In these cases, pass the InputStream straightly to the Document object.
I am sending a SOAP POST that returns some xml. I've been testing on a newer device (Galaxy Nexus with Android 4.1) and it's been working fine. However, I just tried running it on an older device (HTC Desire HD running Android 2.2), and I am getting a ParseException: At line 1, column 0: unclosed token. Here is the relevant code:
String xml = null;
Document doc = null;
String SOAPRequest = "[SOAP REQUEST HERE]";
HttpPost httppost = new HttpPost("[WEBSITE HERE]");
InputStream soapResponse = null;
try {
StringEntity postEntity = new StringEntity(SOAPRequest, HTTP.UTF_8);
postEntity.setContentType("text/xml");
httppost.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
httppost.setEntity(postEntity);
HttpClient httpclient = new DefaultHttpClient();
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient.execute(httppost);
// Convert HttpResponse to InputStream
HttpEntity responseEntity = httpResponse.getEntity();
soapResponse = responseEntity.getContent();
//// printing response here gives me ...<Result><blahblahblah><Result>...
// Get the SearchResult xml
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
doc = db.parse(soapResponse);
} catch ...
NodeList soapNodeList = doc.getElementsByTagName("Result");
xml = soapNodeList.item(0).getFirstChild().getNodeValue();
//// printing xml here gives me "<"
return xml;
Taking a look at the httpResponse, the part that I am interested in looks like this: <Result><blahblahblah></Result>.
When I try to get this xml using the NodeList, <blahblahblah≷ turns into just the character <.
Why is this a problem, and how do I fix it?
This could be relevant:
android DOM parsing with entities in tags
...which leads to this:
http://code.google.com/p/android/issues/detail?id=2607
...which seems to indicate that on earlier Android versions the DOM parser doesn't deal with entity references properly. The bug report there discusses something about how entities are treated as a separate child rather than merged into the adjacent text node(s) which sounds oddly like your situation.
If this is the problem you're having then try switching to using the SAX parser. It's (IMHO) just such an easier XML parser to deal with as well.
I'm validating the form data as the response I'm getting total feed of that URL but i need only session Id from that how can i do this.can any body help regarding this..
Now as below shown way i'm getting response from server how can i get required one from that..
<data>
<limit>
<uname>android</uname>
<pwd>androiddeveloper</pwd>
<sessionid>abcdef56789ghijkl90a<sessionid/>
</limit>
</data>
I solved it from this link and is worked fine for me thanks to that guy who solved it.
HttpResponse response = client.execute(post);
HttpEntity r_entity = response.getEntity();
String xmlString = EntityUtils.toString(r_entity);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
InputSource inStream = new InputSource();
inStream.setCharacterStream(new StringReader(xmlString));
Document doc = db.parse(inStream);
String playcount = "empty";
NodeList nl = doc.getElementsByTagName("playcount");
for(int i = 0; i < nl.getLength(); i++) {
if (nl.item(i).getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
org.w3c.dom.Element nameElement = (org.w3c.dom.Element) nl.item(i);
playcount = nameElement.getFirstChild().getNodeValue().trim();
}
}
You can fire query for that. If the user is authenticated then get user's userId and store in some static variable.
This might you need i think.
I have an android application where I use POST method to get a response. here is my code:
..........................................
HttpResponse httpResponse = httpclient.execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
this works fine and i get a response in xml format but i want to parse that xml file and get the node values. i tried this :
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource());
doc.getDocumentElement().normalize();
but I don't know what should give to new InputSource() because I have to use a XML type HTTPResponse not a url.
Thanks !!!
ok thanks everyone for the replies. i just found out a way to overcome my problem.
http://www.rgagnon.com/javadetails/java-0573.html
try
InputStream is = resEntity .getContent()
Document doc = db.parse(is);
You can use any XML parser like SAX to parse ur XML Data
if your response in xml string format follow
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is=new InputSource();
is.setCharacterStream(new StringReader(xmlString(ur response)))
Document doc = db.parse(is);
getsyncFlag(String feedData) {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(this);
InputSource is=new InputSource();
is.setCharacterStream(new StringReader((feedData)));
xr.parse(is);
}