在我的 iOS 应用程序中,我调用了返回 xml 响应的 WS。我使用 NSXMLParser 解析它。在 web 服务发生一点变化之前,在 iOS 6 上一切正常。现在我不断收到 iOS 6 的这个错误:
发生以下错误:操作无法完成。 (NSXMLParserErrorDomain 错误 100。)(代码:100)
但是,当我在 iOS 7 上尝试时,一切正常。以下是 xml 响应:
旧的 xml 响应:
<User
xmlns="MyService.Rest.A3.Entities"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>George</FirstName>
<LastName>McQuillan</LastName>
<Username>usename</Username>
</User>
新的 xml 响应:
<User
xmlns="http://www.MyService.Rest.A3.Entities"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>George</FirstName>
<LastName>McQuillan</LastName>
<Username>usename</Username>
</User>
所以新的响应只在 iOS 7 上有效,在 iOS 6 上无效。我注意到旧响应中的第一个 xmlns 不是链接,但为什么它适用于 iOS 7?
我遇到了完全相反的情况,
xmlns="MyService.Rest.A3.Entities"
再现在 iOS 6 中调用 parseErrorOccurred
,但在 iOS 7 中没有。在我的测试中,xmlns="http://www.MyService.Rest.A3.Entities"
再现在 iOS 6 和 7 中都成功。
NSXMLParser
在 iOS 6 中似乎验证命名空间是否是有效的绝对 URI。 iOS 7 没有。带有 xmlns="MyService.Rest.A3.Entities"
的命名空间不是有效的绝对 URI。如果您通过 xmllint
(Mac 上通过终端应用程序提供的命令行程序)运行它,它还会报告该命名空间无效:
$ xmllint old.xml
old.xml:2: namespace warning : xmlns: URI MyService.Rest.A3.Entities is not absolute
xmlns="MyService.Rest.A3.Entities"
^
<?xml version="1.0"?>
<User xmlns="MyService.Rest.A3.Entities" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>George</FirstName>
<LastName>McQuillan</LastName>
<Username>usename</Username>
</User>
幸运的是,此错误仅供参考,解析仍在继续,因此,如果您受困于此 XML,您可能只想优雅地检测并忽略它,例如:
if (!([error.domain isEqualToString:NSXMLParserErrorDomain] && error.code == 100)) {
// do your error handling here, ignoring `NSXMLParserErrorDomain` code 100
NSLog(@"%@", error);
}
修复 XML 使其具有有效的 URI 可能更好。
顺便说一下,XML 命名空间规范 指出相对 URI 的使用已被弃用,命名空间值应该为空或绝对 URI。所以,iOS 6 报错的原因是可以理解的,但考虑到
parseErrorOccurred
仅针对致命错误,iOS 7 的行为可能更正确,不再为这种非致命警告调用此方法。
如果你实现下面的 NSXMLParserDelegate 方法
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
然后你可以记录 NSError 并确定它认为发生了什么。当然,它可能会为您提供与您收到的相同的错误代码 100,但其中可能包含更多有用的信息。