KXmlParser выдает исключение Unexpected token в начале передачи RSS

Я пытаюсь разобрать RSS-канал от Monster на Android v.17, используя этот URL:

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

Он начинается так (щелкните URL-адрес выше, если вы хотите увидеть полный XML):

<?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) 

Что на самом деле означает, что он не может обработать 2-й символ в строке 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, но это не помогло

Я исследовал это в Интернете и здесь и не могу найти ничего, что помогло бы


person Bostone    schedule 06.03.2013    source источник


Ответы (1)


Причина, по которой вы получаете сообщение об ошибке, заключается в том, что файл 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));  

Я проверил приведенный выше код, и он хорошо работает для меня.

person Vladimir Mironov    schedule 10.03.2013
comment
Именно поэтому я люблю Stackoverflow! Всегда можно найти человека умнее себя! Заслуженная награда (хотя я не могу присудить ее раньше, чем завтра)! Спасибо! - person Bostone; 11.03.2013
comment
у меня эта ошибка, но у меня есть xml в строковой переменной, что я могу сделать? - person Bachask8; 18.10.2013
comment
Или вы можете сделать data.replaceAll(^.*‹, ‹) У меня работает) - person sagus_helgy; 16.12.2013
comment
@vmironov Каким инструментом вы проанализировали файл? Можете ли вы предоставить имя и ссылку для скачивания, если это возможно? - person Bruno Bieri; 04.08.2014
comment
@viperbone это обычный шестнадцатеричный просмотрщик - person Vladimir Mironov; 05.08.2014