2013-05-09 72 views
0

我正在將爲BlackBerry(Java)編寫的項目移植到Android。該項目包含一些針對org.xmlpull.v1.XmlPullParser接口編寫的xml解析類。實際的解析器實例從外部注入到這些類中。支持良好編碼的內置XmlPullParser的替代

此應用程序分析編碼爲ISO-8859-15(又名拉丁語9)的xml文件。我不能使用UTF-8,不幸的是我需要堅持這種編碼。

老黑莓項目使用kxml2拉解析器。現在,在Android的我嘗試使用內置的解析器,可以這樣獲得的:

XmlPullParser parser = Xml.newPullParser(); 

然後我配置字符編碼:

parser.setInput(<input stream>, "ISO-8859-15"); 

的問題是,這種分析器不支持這種字符編碼。這是拋出的異常:

org.xmlpull.v1.XmlPullParserException: Error parsing document. (position:line -1, column -1) caused by: org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: unknown encoding. 

這真的很奇怪,因爲我知道Android支持這種編碼。證據是這條線運行,沒有例外:但是

String test = new String("hi".getBytes(), "ISO-8859-15"); 

,如果我配置解析器不同的編碼,如UTF-8或Latin-1,它的工作原理。

我想接下來的事情就是用老項目在Android的解析器(kxml2),但後來我得到了新的錯誤:

org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT [email protected]:1 in [email protected]) 

即使我能使用它沒有問題,kxml2沒有收到支持在過去的幾年裏(2006年發佈的最後一個版本),所以我想盡可能使用Android的pull語法分析器,這樣更強大,而且性能更好。

我可以欺騙默認語法分析器,調用parser.setInput(bais, "ISO-8859-1");,因爲這樣它會忽略文件中的XML聲明中的編碼,並且它的工作原理是因爲兩個字符集都具有相同數量的字符,並且其中大部分是相同的。但通過這種方式,有人在查看源代碼時可能會認爲它使用latin-1,實際上它在latin-9中接收輸入,因此會生成latin-9中的字符串。

默認XML Pull Parser是否有任何理由不支持ISO-8859-15?是否有任何替代PULL解析庫具有良好的字符編碼支持?

在此先感謝。


更新:當我寫這個問題時,我測試了OS 2.2和2.3中的默認解析器。然而,閱讀的Javadoc Xml.newPullParser我發現這一點:

注:這實際上是比SAX解析器慢,而且它沒有完全落實。如果你需要一個快速的,主要是實現的解析器,使用這個。如果您需要完整的實施,請使用KXML。

事實上,當在OS​​ 4.x中測試默認解析器時,我得到了第二個異常。看起來像OS 4的內置解析器實際上是KXML!

回答

0

好吧,看起來好像很難找到一個好的XmlPullParser庫,所以我打算使用kxml的解析器遵循javadocs中的建議工廠方法Xml.newPullParser。 (我沒有在在線javadoc中找到這個註釋,只能在eclipse的javadoc窗口中找到。也許我使用的是舊的javadoc,這個註釋後來在Android開始使用kxml作爲內置解析器後被刪除)。

至於使用KXML解析器,這是這個時候拋出的異常:

org.xmlpull.v1.XmlPullParserException: unexpected type (position:END_DOCUMENT [email protected]:1 in [email protected]) 

原來,它是由我的代碼引起的。在初始端口中,我意識到在調用parser.nextText之後,Froyo和Gingerbread中包含的Android內置解析器沒有前進到下一個標記。所以我在這裏和那裏添加了一些parser.nexTag線路以使其工作。然後我再次切換到kXml,但保留了那些額外的行,這使得我的KXmlParser實例在處理文件結尾時變得混亂起來。在到達文件結尾後調用nextTag時引發異常。這也是在文檔解釋了nextTag

調用next(),並返回事件如果是START_TAG或END_TAG 否則拋出異常

相關問題