2010-11-21 25 views
10

Je reçois une erreur "SAXParseException: fin de document inattendue" lorsque j'essaie d'analyser un document XML sur android.SaxParser sur Android: Exception de fin de document inattendue

Le document en question provient de l'api google météo, mais il semble lancer la même erreur quel que soit le fichier xml en question (tant que xml est valide) donc je suppose que c'est un problème avec mon approche, plutôt que le xml.

Cela se fait comme un exercice d'apprentissage, donc je l'ai probablement (je l'espère) négligé quelque chose d'évident =)

J'ai couru le xml par un validateur en ligne, et il revient comme étant bien formé. (Ne peut pas me dire si c'est valide car je n'ai pas de DTD, mais je ne pense pas avoir besoin de la DTD pour analyser le xml).

Voici le code que j'utilise pour essayer d'analyser le fichier:

private void refreshForecast() 
     URL url; 
     try {  
       url = new URL("http://192.168.1.66:8000/google4.xml"); 

       URLConnection connection = url.openConnection(); 
       HttpURLConnection httpConnection = (HttpURLConnection)connection; 
       int responseCode = httpConnection.getResponseCode(); 

       if (responseCode == HttpURLConnection.HTTP_OK) { 
         InputStream in = httpConnection.getInputStream();   
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
         DocumentBuilder db = dbf.newDocumentBuilder(); 

         // falls over here parsing the xml. 
         Document dom = db.parse(in);  
       } 
     } catch (ManyExceptions e) { 
     .... 
} 

Une version dénudation du xml qui produit l'erreur est:

<?xml version="1.0"?> 
<xml_api_reply version="1"> 
     <weather> 
      <forecast_information> 
        <city>Hamilton</city> 
      </forecast_information> 
     </weather> 
</xml_api_reply> 

Le stacktrace est:

11-20 06:17:24.416: WARN/System.err(406): org.xml.sax.SAXParseException: Unexpected end of document 
11-20 06:17:24.416: WARN/System.err(406):  at org.apache.harmony.xml.parsers.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:131) 
11-20 06:17:24.416: WARN/System.err(406):  at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:110) 
11-20 06:17:24.426: WARN/System.err(406):  at com.dave.nzweather.WeatherApp.refreshForecast(WeatherApp.java:159) 
11-20 06:17:24.426: WARN/System.err(406):  at com.dave.nzweather.WeatherApp.onCreate(WeatherApp.java:100) 
11-20 06:17:24.426: WARN/System.err(406):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
11-20 06:17:24.438: WARN/System.err(406):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
11-20 06:17:24.438: WARN/System.err(406):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
11-20 06:17:24.446: WARN/System.err(406):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
11-20 06:17:24.446: WARN/System.err(406):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
11-20 06:17:24.456: WARN/System.err(406):  at android.os.Handler.dispatchMessage(Handler.java:99) 
11-20 06:17:24.456: WARN/System.err(406):  at android.os.Looper.loop(Looper.java:123) 
11-20 06:17:24.456: WARN/System.err(406):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
11-20 06:17:24.466: WARN/System.err(406):  at java.lang.reflect.Method.invokeNative(Native Method) 
11-20 06:17:24.466: WARN/System.err(406):  at java.lang.reflect.Method.invoke(Method.java:521) 
11-20 06:17:24.466: WARN/System.err(406):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
11-20 06:17:24.476: WARN/System.err(406):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
11-20 06:17:24.476: WARN/System.err(406):  at dalvik.system.NativeStart.main(Native Method) 
11-20 06:17:24.486: WARN/ROGER(406): org.xml.sax.SAXParseException: Unexpected end of document 

Dans un souci de concision, je ne l'ai pas inclus le code XML d'origine, mais il est juste la norme weath er xml de googles nourrir.

J'ai également essayé quelques fichiers XML complètement différents, (y compris l'exemple de http://www.ibm.com/developerworks/xml/library/x-android/) et ils donnent tous la même erreur. (Ils valident tous aussi bien formés quand je les lance à travers un validateur XML en ligne).

Cela me fait penser que ce n'est pas un problème avec le XML, mais plutôt avec la façon dont j'essaie de le nourrir dans l'analyseur.

Vive

Dave Smylie

+0

Avez-vous déjà essayé de lire le fichier complet? Je me souviens d'un problème comme celui-là il y a longtemps, peut-être que cela aide. –

+0

Je suppose que - je vide le fichier récupéré via android.util.log et il montre le fichier complet là-dedans. Cependant, en cours d'exécution de cet inputtream dans un buffer de chaîne, il est possible que le journal obtienne un flux complètement terminé, où parse() obtient un flux incomplet .... Je vais voir si je peux le convertir en un stringbuffer et parse que ... –

Répondre

3

En regardant votre code, il semble que vous essayez de récupérer le fichier hors d'un ordinateur sur votre réseau. Avez-vous essayé d'ouvrir cette URL dans un navigateur pour vérifier si elle envoie réellement le fichier XML?

Alternativement, vous pouvez également vérifier avec Wireshark quelle réponse votre téléphone obtient. Je suppose que vous n'avez tout simplement pas récupéré le document XML, mais une page d'erreur 404.

+0

J'ai d'abord pensé que les problèmes de réseau pourraient être le problème, donc je suis en train de le récupérer sur un serveur web local. Je peux voir la requête se terminer correctement dans le journal du serveur et je vider le contenu du fichier xml récupéré à éclipse via android.util.log donc je suis assez sûr qu'il reçoit le fichier d'accord. . . –

+0

@Dave Smylie: Quel était le problème? –

+1

Je ne suis toujours pas sûr - je soupçonne que le flux d'entrée que je passais dans parse() ne récupérait pas complètement le document. (Bien que quand j'ai converti le flux d'entrée en une chaîne et l'ai jeté dans le journal il montrerait le document complet - donc peut-être le flux d'entrée ne bouge pas .... de toute façon, dès que je viens de passer un uri et je laisse le document disparaître le problème –

4

Résolu (un peu) ...

je vis sax.parser pourrait aussi prendre un uri directement (au lieu du flux d'entrée).

Dès que j'ai essayé, bien qu'il soit traité, et le code était beaucoup plus court = de)

Merci pour l'aide.

String weatherFeed = "http://192.168.1.66:8000/google.xml"; 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document dom = db.parse(weatherFeed); 
3

Votre problème peut avoir été causé par un problème de codage.

Essayez de créer votre inputStream via un ByteArrayInputStream avec encodage UTF-8 comme ci-dessous et voir si cela fonctionne. Ceci, (ci-dessous), est ce que j'ai dû utiliser quand j'avais une chaîne de XML, mais cela peut toujours être un problème via le flux inputes que vous utilisez.

String sData = "..Your XML in here.."; 
DocumentBuilder db = dbf.newDocumentBuilder(); 
InputStream is = new ByteArrayInputStream(sData.getBytes("UTF-8")); 
Document doc = db.parse(is); 

Cela suppose que votre XML est a encodage UTF-8 spécifié comme celui-ci

<?xml version="1.0" encoding="UTF-8" ?> 

Sinon, vous devez vous assurer que votre encodage défini dans votre InputStream est le même que celui défini dans votre XML.