4

我正在尝试使用以下 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) 中的违规行。类型 == TEXT 计算为true

if (depth == 0 && (type == ENTITY_REF || type == TEXT || type == CDSECT)) {
    throw new XmlPullParserException("Unexpected token", this, null);
}

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

我在网上和这里做了研究,找不到任何有用的东西

4

1 回答 1

34

您收到错误的原因是 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));  

我检查了上面的代码,它对我很有效。

于 2013-03-10T05:59:42.130 回答