【问题标题】:Reading NSData from a XML CData section instead of an NSString从 XML CData 部分而不是 NSString 读取 NSData
【发布时间】:2012-01-05 13:00:53
【问题描述】:

我很可能最终会回答我自己的问题,因为我需要先修复这个错误,然后才能继续,但它在这里是为了文档目的。注意:我没有像我发现的所有其他问题/答案一样使用 SAX 解析器。

NSMutableData* data = ...

NSXMLNode* nodeCDATA= [[NSXMLNode alloc] initWithKind:NSXMLTextKind options:NSXMLNodeIsCDATA];
[nodeCDATA setObjectValue:data];

NSAssert([nodeCDATA.objectValue isKindOfClass:[NSData class]], @"NSXMLNode setObjectValue didn't use a NSData");

需要注意的是,在同一个函数中,最后的 NSAssert 不会触发。 然而,在将 xml 发送到服务器后,我得到一个 NSString 作为返回类型。

NSXMLNode* nodeCDATA= [dx childAtIndex:0];

id obj= nodeCDATA.objectValue;
if (![obj isKindOfClass:[NSData class]])
    NSLog(@"Why am I getting a %@ returned from a CDATA section!?",[obj class]);

输出是...

2012-01-05 13:58:29.336 auth[18773:1f03] Why am I getting a __NSCFString returned from a CDATA section!?

感谢您的帮助。

===== 更新 =====

问题仍然悬而未决。我发现的最佳解决方案是找到一个外部 base64 加密解决方案,将 NSMutableData 编码为 NSString,然后使用 setStringValue。然后我用base64的decrypt对stringValue返回的字符串进行解密,避免了这个问题。

确切地说,我现在使用来自http://www.cocoadev.com/index.pl?BaseSixtyFour 的 - (NSString *)base64Encoding 来对它进行 jimmy 装配,但我很可能会将 NSData 字节的原始写入实现为 BSON 格式,看看是否会削减它。我读到 base64 使数据大小增加了大约 33%,我想如果可能的话我想避免这种情况。

上述解决方案仍然非常受欢迎。

=== 更多更新 ===

我研究过的一些选项是 DTD 和 XSL。很久以前,MSXML.dll 中也存在同样的问题。如果我可以分配一个 DTD 或进行 XSL 转换以使 Apple API 相信我的数据是我希望返回为 NSData 的 base64 字符数据,那就太好了。有人有这方面的代码吗?我确实在 DTD 中发现了 xs:base64Binary 标记的非规范使用,但我还没有尝试过 Apple ID 是否接受它。太多的工作只是为了看看它是否有效。

【问题讨论】:

    标签: objective-c xml dom cdata


    【解决方案1】:

    CDATA 部分并非旨在让您传递二进制数据。它们专门用于标记必须仅解释为字符数据而非标记的内容部分。 CDATA 节点内的数据和文本节点内的数据之间没有语义差异。如果需要对二进制数据进行编码,则需要将其转换为与 UTF-8 兼容的内容。 Base64 是典型的选择。

    这是来自wikipedia page的相关段落:

    XML 文档的新作者经常误解 CDATA 部分的用途,错误地认为它的目的是“保护”数据在处理过程中不被视为普通字符数据。一些用于处理 XML 文档的 API 确实提供了对 CDATA 部分的独立访问的选项,但这些选项的存在超出了 XML 处理系统的正常要求,并且仍然不会改变数据的隐含含义。字符数据是字符数据,不管它是通过 CDATA 节还是普通标记表示的。

    所有这一切的最终结果是,虽然NSXMLNode API 可以接受NSData 作为输入,但它们没有义务在解析外部文档后为您提供NSData。实际上,由于 CDATA 部分的内容是字符数据,因此 NSXMLNode 返回 NSString 更正确(正如您所说,它正在这样做)。

    【讨论】:

    • 凯文,你是完全正确的。但是,我正在寻找的是一种在任何情况下都可以获取该 NSData 的方法。我可能使用 xs:base64Binary 标记查看了 DTD 和 XSL,但我没有看到完成这项工作的明确方法。
    • 正如我也说过的,当我在同一个函数(NSAssert 语句)中从节点中提取数据时,数据作为 NSData 返回。所以,我想在传输后达到同样的效果。
    • @PLG:当您将objectValue 设置为NSData 然后立即再次将其拉出时,它会为您提供与您提供的完全相同的NSData。但是,如果您解析一个 XML 文档,然后向节点询问其objectValue,您将得到一个NSString。我建议改用stringValuesetStringValue:,并在NSDataNSString 之间使用您自己的转换(例如使用base64 或类似的)
    • 感谢您的回复凯文。我唯一觉得奇怪的是......为什么Apple会包含一个功能,您可以将NSData传递给XML文档,从而它会自动为您存储(有些阅读您发现它是base64)没有办法通过 API 以某种方式读取该格式。这里一定少了点什么。
    • @PLG:他们会做什么选择?崩溃?
    猜你喜欢
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多