詳解iPhone應(yīng)用程序中非UTF-8里的XML
iPhone應(yīng)用程序中非UTF-8里的XML是本文要介紹的內(nèi)容,主要介紹了iphone里的UTF-8的XML應(yīng)用,先來看詳細內(nèi)容。做iPhone的網(wǎng)絡(luò)應(yīng)用,處理XML是家常便飯,NSXMLParser用起來還是得心應(yīng)手的。不過這個東西,處理非UTF-8,會解析失敗。這篇文章就是想和大家一起分享一些這方面開發(fā)的新的。
我們在某個RSS地址,可以得到下面這樣的XML文件。我這里只是截取一段,
- <?xml version="1.0" encoding="big5"?>
- <rss version="2.0">
- <channel>
- <title>RTHK On Internet - 即 時 新 聞</title>
- <link><![CDATA[http://www.rthk.org.hk/rthk/news/expressnews/]]></link>
- <description>RTHK On Internet - 即 時 新 聞</description>
- <pubDate>Sun, 11 Oct 2009 15:02:02 +0800</pubDate>
- <item>
- <title><![CDATA[衞生署要求浸會醫(yī)院4周內(nèi) 就產(chǎn)婦死亡個案提交報告 ]]></title>
- <link><![CDATA[http://www.rthk.org.hk/rthk/news/expressnews/20091011/news_20091011_55_618483.htm]]></link>
- <description><![CDATA[
衞生署昨晚已經(jīng)收到浸會醫(yī)院通知,有一宗產(chǎn)婦死亡個案,浸會醫(yī)院需要在4星期內(nèi)向衞生署提交報告,案件亦交由死因庭跟進。
衞生署數(shù)字顯示,由07年至今年8月,共接獲97宗私家醫(yī)院醫(yī)療事故的通報。去年發(fā)生的事故中,最多的是進行手術(shù)或介入程序期間出現(xiàn)併發(fā)癥,其次還有孕婦及產(chǎn)婦死亡,或與孕婦在分娩過程中,生產(chǎn)時,或產(chǎn)後出現(xiàn)嚴重併發(fā)癥;部份則包括初生嬰兒出現(xiàn)死亡或嚴重受傷;錯誤為病人或身體部位進行外科或介入手術(shù)程序等。
- ]]></description>
- <pubDate>
- Sun, 11 Oct 2009 14:50:46 +0800
- </pubDate>
- </item>
- </channel>
- </rss>
這是一個很常用的RSS返回的XML,是繁體中文的,編碼格式是big5。說編碼格式是big5有兩層意思:
(1)網(wǎng)絡(luò)流返回的NSData是big5編碼的。所以這樣的NSData送給NSXMLParser是不能正確解析的。
(2)第一句話指明了XML文件也是用big5編碼的。
對應(yīng)于上面兩個問題,我的解決思路是:
(1)把Big5編碼的NSData轉(zhuǎn)換成UTF-8編碼的NSData
(2)將第一行<?xml version="1.0" encoding="big5"?>轉(zhuǎn)換成<?xml version="1.0" encoding="utf-8"?>
第二個轉(zhuǎn)換不難,只要我們有NSString對象。第一個轉(zhuǎn)換要用到CFStringRef,代碼如下:
- CFStringRef big5Str = CFStringCreateWithBytes(NULL,
- [inData bytes],
- [inData length],
- kCFStringEncodingBig5_HKSCS_1999,
- false); //[A]
- if (NULL == big5Str) {
- return nil;
- }
- else {
- NSString *big5NSString = (NSString *)big5Str;
- NSString *utf8NSString = [big5NSString stringByReplacingOccurrencesOfString:@"<?xml version=\"1.0\" encoding=\"big5\"?>"
- withString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"]; //[B]
- return [utf8NSString dataUsingEncoding:NSUTF8StringEncoding]; //[C]
- }
- CFStringRef big5Str = CFStringCreateWithBytes(NULL,
- [inData bytes],
- [inData length],
- kCFStringEncodingBig5_HKSCS_1999,
- false); //[A]
- if (NULL == big5Str) {
- return nil;
- }
- else {
- NSString *big5NSString = (NSString *)big5Str;
- NSString *utf8NSString = [big5NSString stringByReplacingOccurrencesOfString:@"<?xml version=\"1.0\" encoding=\"big5\"?>"
- withString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"]; //[B]
- return [utf8NSString dataUsingEncoding:NSUTF8StringEncoding]; //[C]
- }
思路就是先把NSData轉(zhuǎn)成CFStringRef的對象[A], 然后這個對象再轉(zhuǎn)成UTF-8的NSData [C],這就解決了問題[1]
中間的[B]就解決了問題[2]。這里要注意兩個問題:
(1)如果你的XML編碼是GBK,或者GB23120或者其他的,kCFStringEncodingBig5_HKSCS_1999要換成你對應(yīng)的編碼方式。
(2)如果你的XML編碼也是big5的,也許kCFStringEncodingBig5_HKSCS_1999并不適合你的應(yīng)用。因為對應(yīng)big5的編碼常量還有兩種,他們是:
- kCFStringEncodingBig5_E
- kCFStringEncodingBig5。
這個你可以查閱幫助文檔,然后一個個試。
然后把return的NSData送到NSXMLParser,就可以正確解析了。可是還沒有結(jié)束,大家仔細看看XML文件里面還有衞這樣的東西。這個是繁體中文”衛(wèi)“字,我們?nèi)绻惶幚磉@個東西,顯示給用戶看得就是衞,這顯然是不行的。這個其實也好辦,只需要用下面這句話就可以把一個number轉(zhuǎn)成NSString了:
- [NSString stringWithFormat:@"%C", number]
這個number就是34910,是一個整數(shù),十進制的整數(shù)(不是十六進制的)。到這里,整個處理過程就OK了,我們就可以正確得到Big5的RSS新聞了。因為這是一個客戶項目,不過我可以給各小截圖大家看看,如圖所示:
小結(jié):詳解iPhone應(yīng)用程序中非UTF-8里的XML的內(nèi)容介紹完了,希望本文對你有所幫助!