【问题标题】:NSXMLParser error when encountering a 'special' character遇到“特殊”字符时出现 NSXMLParser 错误
【发布时间】:2012-06-26 16:41:18
【问题描述】:

我正在尝试使用 NSXMLParser 来解析一个看起来像这样的 XML 文件:

<?xml version="1.0" encoding="us-ascii"?>
<teams>
    <team id = "A1">
        <player1>John</player1>
        <player2>José</player2>
    </team>
    ...
</teams>

我使用以下代码:

NSString *urlString = [NSString stringWithFormat:@"http://www....abc.php?category=%@&poule=%c", @"S", 'B'];  // Obviously, this contains an actual web address
NSURL *url = [NSURL URLWithString:urlString];
NSData *xml = [[NSData alloc] initWithContentsOfURL:url];   // <==
NSXMLParser *xmlParserObject = [[NSXMLParser alloc]initWithData:xml];
[xmlParserObject setDelegate:self];
[xmlParserObject parse];

我实现了 didStartElement、foundCharacters、didEndElement 和 parserErrorOccurred 委托函数。

这一切都很顺利,直到遇到“特殊”字符,例如 é。委托方法parserErrorOccurred报如下错误:

parser error: Error Domain=NSXMLParserErrorDomain Code=1544 "The operation couldn’t be completed. (NSXMLParserErrorDomain error 1544.)"
parser error: Error Domain=NSXMLParserErrorDomain Code=5 "The operation couldn’t be completed. (NSXMLParserErrorDomain error 5.)"

然后我将标有“

NSError *error;
NSData *xml = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
if (xml == nil) {
    NSLog(@"*** Fatal error: %@\nuserInfo:%@", error, [error userInfo]);
}

除上述错误外,还出现以下错误:

 *** Fatal error: Error Domain=NSCocoaErrorDomain Code=261 "The operation couldn’t be completed. (Cocoa error 261.)" UserInfo=0x8158d90 {NSURL=http://www....abc.php?category=S&poule=B, NSStringEncoding=4}
userInfo:{
    NSStringEncoding = 4;
    NSURL = "http://www....abc.php?category=S&poule=B";
}

我还尝试将 NSUTF8StringEncoding 替换为任何其他编码器,例如 NSISOLatin1StringEncoding、NSUTF16StringEncoding、NSASCIIStringEncoding、NSUnicodeStringEncoding 等。这导致了以下错误:

 -[__NSCFString bytes]: unrecognized selector sent to instance 0x6e4cbc0
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x6e4cbc0'
*** First throw call stack:
(0x12d0022 0x1781cd6 0x12d1cbd 0x1236ed0 0x1236cb2 0xce5f51 0xb447 0xaa89 0x1f2e330 0x1f2f439 0x908b9b24 0x908bb6fe)
terminate called throwing an exception(lldb) 

我无法控制 XML 的内容,但如果它确实包含不正确的信息,那么也许我可以与网站管理员交谈。

我可以将 é 字符显示为 'e' 或 '?'如果需要的话。

非常感谢任何有关导致此错误的原因以及如何纠正或绕过它的建议。

发送!

--GB

【问题讨论】:

    标签: xml parsing xml-parsing nsxmlparser


    【解决方案1】:

    我找到了解决此问题的方法(不是解决方案)。为了从 NSURL 到 NSData,我使用了以下代码:

            NSError *error;
            NSString *xmlText = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
            xmlText = [xmlText stringByReplacingOccurrencesOfString:@"é" withString:@"e"];
            NSData *xml = [xmlText dataUsingEncoding:NSASCIIStringEncoding];
    

    所以基本上,我

    • 将 NSURL 转换为 NSString
    • 通过替换“特殊”字符来编辑该字符串
    • 使用编辑后的字符串创建 NSData

    我还发现我必须使用 NSASCIIStringEncoding 而不是 NSUTF8StringEncoding(这是 XML 指定的,但之前失败了)。

    无论如何,仍然欢迎提出真正解决问题的建议,但这种绕过方式暂时对我有用......

    【讨论】:

      【解决方案2】:

      如果出现无效的 utf-8 字符,最好先“清理”从源接收的数据,然后再将其处理给 NSXMLParser。正如在处理 NSXMLParser 时经常建议的那样,将数据转换为 ascii 并不总是一个好主意,例如当您的源代码包含西里尔字符时。

      在 Swift 中可以这样做:

      var buffer = data // malformed UTF-8
      buffer.append(0 as UInt16)
      let cleanBuffer = buffer.withUnsafeBytes { (p: UnsafePointer<CChar>) in String(cString: p) }
      let cleanString = cleanBuffer.replacingOccurrences(of: "\u{FFFD}", with: String())
      let cleanData = clean.data(using: String.Encoding.utf8) {
         self.parser = XMLParser(data: cleanData) // Assuming a 'parser' variable is already present
      }
      

      基于Cleaning malformed UTF8 strings

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-09
        • 1970-01-01
        • 2011-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多