我正在尝试使用以下 URL 在 Android v.17 上解析来自 Monster 的 RSS 提要:

http://rss.jobsearch.monster.com/rssquery.ashx?q=java

要获取内容,我以以下方式使用 HttpUrlConnection

this.conn = (HttpURLConnection) url.openConnection();
this.conn.setConnectTimeout(5000);
this.conn.setReadTimeout(10000);
this.conn.setUseCaches(true);
conn.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
is = new InputStreamReader(url.openStream());

返回的是我可以说的(我也验证过)一个合法的 RSS
Cache-Control:private
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:5958
Content-Type:text/xml
Date:Wed, 06 Mar 2013 17:15:20 GMT
P3P:CP=CAO DSP COR CURa ADMa DEVa IVAo IVDo CONo HISa TELo PSAo PSDo DELa PUBi BUS LEG PHY ONL UNI PUR COM NAV INT DEM CNT STA HEA PRE GOV OTC
Server:Microsoft-IIS/7.5
Vary:Accept-Encoding
X-AspNet-Version:2.0.50727
X-Powered-By:ASP.NET

它是这样开始的(如果您想查看完整的 XML,请单击上面的 URL):
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
  <channel>
    <title>Monster Job Search Results java</title>
    <description>RSS Feed for Monster Job Search</description>
    <link>http://rss.jobsearch.monster.com/rssquery.ashx?q=java</link>

但是当我尝试解析它时:
final XmlPullParser xpp = getPullParser();
xpp.setInput(is);
for (int type = xpp.getEventType(); type != XmlPullParser.END_DOCUMENT; type = xpp.next()) { /* pasing goes here */ }

该代码立即在 type = xpp.next() 上窒息,并出现以下异常
03-06 09:27:27.796: E/AbsXmlResultParser(13363): org.xmlpull.v1.XmlPullParserException:
   Unexpected token (position:TEXT @1:2 in java.io.InputStreamReader@414b4538)

这实际上意味着它无法处理第 1 行的第二个字符 <?xml version="1.0" encoding="utf-8"?>
以下是 KXmlParser.java (425-426) 中的违规行。 type == TEXT 计算为 true
if (depth == 0 && (type == ENTITY_REF || type == TEXT || type == CDSECT)) {
    throw new XmlPullParserException("Unexpected token", this, null);
}

有什么帮助吗?我确实尝试将解析器设置为 XmlPullParser.FEATURE_PROCESS_DOCDECL = false 但这没有帮助

我确实在网上和这里进行了研究,但找不到任何有用的信息

最佳答案

您收到错误的原因是 xml 文件实际上并不以 <?xml version="1.0" encoding="utf-8"?> 开头。它以三个特殊字节 EF BB BF 开头,即 Byte order mark
InputStreamReader不会自动处理这些字节,因此您必须手动处理它们。最简单的方法是使用 BOMInpustStream 库中的 Commons IO :

this.conn = (HttpURLConnection) url.openConnection();
this.conn.setConnectTimeout(5000);
this.conn.setReadTimeout(10000);
this.conn.setUseCaches(true);
conn.addRequestProperty("Content-Type", "text/xml; charset=utf-8");
is = new InputStreamReader(new BOMInputStream(conn.getInputStream(), false, ByteOrderMark.UTF_8));

我已经检查了上面的代码,它对我来说效果很好。

10-07 12:50
查看更多