ios開發中經常會用到解析XML,但是iOS提供的NSXmlParser只能解析encoding是utf-8的XML文件。即xml文件開頭必須是
<!--?xml version="1.0" encoding="utf-8"?-->
在中文網頁中,經常會碰到gb2312或GBK編碼的XML文件,如
<!--?xml version="1.0" encoding="gb2312"?-->
當iphone開發中的NSXMLParser碰到非utf-8編碼時,會直接觸發parser:parseErrorOccurred:,返回的錯誤編碼是31,之後直接退出。
解決這個問題的思路當然是把非utf-8編碼轉換為utf-8編碼,這個功能可以通過NSString類進行轉換。
問題在於如何判斷文件的編碼是什麼。這一問題的解決思路在於ASCII碼在任何編碼方式下都是一樣的,這樣,只要將XML文件開頭的若干字節(大部分XML文件的Encoding在頭部前面位置)內容直接當成utf-8編碼讀出來,可以從中檢索是否有您要轉換的編碼。
以處理GB2312編碼轉換為例:
- //取XML文件的前40個字節
- NSData * xmldata = [self.ItemData subdataWithRange:NSMakeRange(0,40)];
-
- //以UTF-8編碼進行解碼
- NSString *xmlstr = [[NSString alloc] initWithData:xmldata encoding:NSUTF8StringEncoding];
- //NSLog(@"XML HEADER: %@", xmlstr);
- //搜索GB2312,如果找到,就對整個文件進行編碼轉換
- if ([xmlstr rangeOfString:@"\"GB2312\"" options:NSCaseInsensitiveSearch].location != NSNotFound)
- {
- // NSLog(@"GB2312 encoding founded.");
-
- NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
- NSString *utf8str = [[[NSString alloc] initWithData:self.ItemData encoding:enc] autorelease];
- utf8str = [utf8str stringByReplacingOccurrencesOfString:@"\"GB2312\"" withString:@"\"utf-8\"" options:NSCaseInsensitiveSearch range:NSMakeRange(0,40)];
- NSData *newData = [utf8str dataUsingEncoding:NSUTF8StringEncoding];
- self.ItemData = newData;
- }
最後提下我碰到的一個有意思的問題,即有時候下載的XML文件被HTML Process過了。我發現原因可能是URL中的大小寫問題。如http://news.163.com/special/00011K6L/rss_newstop.xml這個地址,如果K6L變成k6l,下載的XML文件就變了,大家可以試試.
如果用HPPLE解析HTML,碰到中文GB2312或GBK編碼的網頁,要先用gb編碼解碼,然後替換其中的gb字符串,再用utf8編碼成data給parser就能解析中文網頁了。