Android 上的 SaxParser:意外的文档结束异常

发布于 2024-10-03 06:31:19 字数 4022 浏览 5 评论 0原文

尝试在 Android 上解析 xml 文档时,出现“SAXParseException:文档意外结束”错误。

有问题的文档来自 google 天气 api,但无论有问题的 xml 文件如何(只要 xml 有效),它似乎都会抛出相同的错误,所以我怀疑这是我的方法的问题,而不是 xml 的问题。

这是作为学习练习来完成的,所以我可能(希望)忽略了一些明显的事情 =)

我已经通过在线验证器运行了 xml,并且它返回格式良好。 (无法告诉我它是否有效,因为我没有 DTD,但我认为我不需要 DTD 来解析 xml)。

这是我用来尝试解析文件的代码:

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) {
        .... 
} 

产生错误的 xml 的简化版本是:

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

堆栈跟踪是:

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

为了简洁起见,我没有包含原始 xml,但它只是来自 google feed 的标准天气 xml。

我还尝试了一些完全不同的 xml 文件(包括 http 中的示例) ://www.ibm.com/developerworks/xml/library/x-android/),它们都给出相同的错误。 (当我通过在线 xml 验证器运行它们时,它们也都得到了良好的验证)。

这让我认为这不是 xml 的问题,而是我如何将其输入解析器的问题。

干杯

戴夫·斯迈利

I'm getting a "SAXParseException: Unexpected end of document" error when trying to parse an xml document on android.

The document in question is from the google weather api, but it seems to throw the same error regardless of the xml file in question (as long as the xml is valid) so I suspect it's a problem with my approach, rather than the xml.

This is being done as a learning exercise, so I've probably (hopefully) overlooked something obvious =)

I've run the xml through an online validator, and it comes back as being well formed. (Can't tell me if it's valid as I don't have a DTD, but I dont think I need the DTD to parse the xml).

This is the code that I'm using to try and parse the file:

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) {
        .... 
} 

A cutdown version of the xml that produces the error is:

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

The stacktrace is:

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

In the interest of brevity, I've not included the original xml, but it's just the standard weather xml from googles feed.

I've also tried a few completely different xml files, (including the sample from http://www.ibm.com/developerworks/xml/library/x-android/) and they all give the same error. (They also all validate as well formed when I run them through an online xml validator).

This makes me think that it's not a problem with the xml, but rather with how I'm trying to feed it into the parser.

Cheers

Dave Smylie

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倾城泪 2024-10-10 06:31:19

解决了(有点)...

我看到 sax.parser 也可以直接接受 uri(而不是输入流)。

当我尝试这样做时,它解析得很好,并且代码短了很多=)

感谢您的帮助。

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

Solved (sort of)...

I saw sax.parser could also take in a uri directly (instead of the input stream).

As soon as I tried that, it parsed okay, and the code was a whole lot shorter =)

Thanks for the help.

  String weatherFeed = "http://192.168.1.66:8000/google.xml";
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  DocumentBuilder db = dbf.newDocumentBuilder();
  Document dom = db.parse(weatherFeed);
感情洁癖 2024-10-10 06:31:19

查看您的代码,您似乎正在尝试从网络上的计算机上获取文件。您是否尝试过在浏览器中打开该 URL 以检查它是否真的在发送 XML 文件?

或者,您也可以使用 Wireshark 检查您的手机收到的答复。我的猜测是,您根本没有得到 XML 文档,而是得到了 404 错误页面。

Looking at your code it seems that you are trying to fetch the file off a computer on your network. Have you tried to open that URL in a browser to check if it is really sending the XML file?

Alternatively you can also check with Wireshark what answer your phone gets. My guess is that you simply don't get the XML document back but a 404 error page.

她说她爱他 2024-10-10 06:31:19

您的问题可能是由编码问题引起的。

尝试通过 ByteArrayInputStream 使用 UTF-8 编码创建 inputStream,如下所示,看看是否有效。当我有一个 XML 字符串时,(如下)我必须使用它,但通过您正在使用的输入流,它可能仍然是一个问题。

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

这假设您的 XML 具有像这样指定的 UTF-8 编码

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

,否则您应该确保您的 InputStream 中定义的编码与 XML 中定义的编码相同。

Your problem may have been caused by an encoding issue.

Try creating your inputStream via a ByteArrayInputStream with UTF-8 encoding like below and see if that works. This, (below), is what I had to use when I had a String of XML, but it may still be an issue via the inputestream you are using.

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

This assumes that your XML is has UTF-8 encoding specified like this

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

Otherwise you should make sure your encoding defined in your InputStream is the same as that defined in your XML.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文