NSXMLParserInvalidCharacterError #9
这是我遇到奇怪字符时遇到的错误(例如从单词复制并粘贴到 Web 表单中的引号,最终出现在提要中)。我正在使用的提要没有提供编码,他们不希望我让他们改变它。这就是我在标题中得到的全部内容:
< ?xml version="1.0"?> < rss version="2.0">
解析提要时如何处理非法字符?我是否在解析之前扫描数据?API中是否缺少我的东西?有没有人处理过这个问题?
NSXMLParserInvalidCharacterError #9
这是我遇到奇怪字符时遇到的错误(例如从单词复制并粘贴到 Web 表单中的引号,最终出现在提要中)。我正在使用的提要没有提供编码,他们不希望我让他们改变它。这就是我在标题中得到的全部内容:
< ?xml version="1.0"?> < rss version="2.0">
解析提要时如何处理非法字符?我是否在解析之前扫描数据?API中是否缺少我的东西?有没有人处理过这个问题?
NSString *dataString = [[[NSString alloc] initWithData:webData encoding:NSASCIIStringEncoding] autorelease];
NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
解决了我的问题...
如果失败, NSString-initWithData:encoding:
方法会返回nil
,因此您可以尝试一种又一种编码,直到找到一种可以转换的编码。这并不能保证您将正确转换所有字符,但如果您的提要源没有向您发送正确编码的 XML,那么您可能不得不忍受它。
基本思想是:
// try the most likely encoding
NSString xmlString = [[NSString alloc] initWithData:xmlData
encoding:NSUTF8StringEncoding];
if (xmlString == nil) {
// try the next likely encoding
xmlString = [[NSString alloc] initWithData:xmlData
encoding:NSWindowsCP1252StringEncoding];
}
if (xmlString == nil) {
// etc...
}
为了通用和健壮,您可以执行以下操作直到成功:
1.) 尝试 HTTP 响应的 Content-Type 标头中指定的编码(如果有)
2.) 检查响应数据的开头是否有字节顺序标记,如果找到,请尝试指定的编码
3.)查看前两个字节;如果您发现空白字符或“<”与 nul/零字符配对,请尝试 UTF-16(类似地,您可以检查前四个字节以查看是否有 UTF-32)
4.) 扫描数据的开头寻找<?xml ... ?>
处理指令,并在encoding='something'
里面寻找;试试那个编码。
5.) 尝试一些常见的编码。如果您的数据源是英文,请务必检查 Windows Latin-1、Mac Roman 和 ISO Latin-1。
6.) 如果上述方法都不起作用,您可以尝试删除所有大于 127 的字节(或替换“?”或其他 ASCII 字符)并使用 ASCII 编码转换数据。
如果此时您还没有 NSString,那么您应该会失败。如果您确实有一个 NSString,您应该encoding
在处理指令中查找声明<?xml ... ?>
(如果您还没有在步骤 4 中)。如果它在那里,您应该使用该编码将 NSString 转换回 NSData ;如果它不存在,您应该使用 UTF-8 编码转换回来。
此外,CFStringConvertIANACharSetNameToEncoding()
and函数可以帮助从标头或处理指令中CFStringConvertEncodingToNSStringEncoding()
获取与编码名称一起使用的 NSStringEncoding 。Content-Type
<?xml ... ?>
您还可以像这样从 xml 中删除该编码行:
int length = str.length >100 ? 100:str.length;
NSString*mystr= [str stringByReplacingOccurrencesOfString:@"encoding=\".*?\""
withString:@""
options:NSRegularExpressionSearch
range:NSMakeRange(0, length)];