解決NSXmlParser無法解析非utf-8編碼的XML問題的方法

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就能解析中文網頁了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章