Android 上的 SaxParser:意外的文档结束异常
尝试在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
解决了(有点)...
我看到 sax.parser 也可以直接接受 uri(而不是输入流)。
当我尝试这样做时,它解析得很好,并且代码短了很多=)
感谢您的帮助。
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.
查看您的代码,您似乎正在尝试从网络上的计算机上获取文件。您是否尝试过在浏览器中打开该 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.
您的问题可能是由编码问题引起的。
尝试通过 ByteArrayInputStream 使用 UTF-8 编码创建 inputStream,如下所示,看看是否有效。当我有一个 XML 字符串时,(如下)我必须使用它,但通过您正在使用的输入流,它可能仍然是一个问题。
这假设您的 XML 具有像这样指定的 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.
This assumes that your XML is has UTF-8 encoding specified like this
Otherwise you should make sure your encoding defined in your InputStream is the same as that defined in your XML.