从 XML CData 部分而不是 NSString 读取 NSData
我很可能最终会回答我自己的问题,因为我需要先修复这个错误,然后才能继续,但它是出于文档目的而放在这里的。注意:我没有像我发现的其他问题/答案那样使用 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的解密来解密stringValue返回的字符串,避免了这个问题。
确切地说,我使用了来自 http://www.cocoadev.com 的 - (NSString *)base64Encoding /index.pl?BaseSixtyFour 吉米现在装备它,但我很可能将 NSData 字节的原始写入实现为 BSON 格式,看看是否会削减它。我读到,base64 使数据大小增加了约 33%,我想如果可能的话我想避免这种情况。
上述解决方案仍然非常受欢迎。
=== 更多更新 ===
我研究过的一些选项是 DTD 和 XSL。很久以前,MSXML.dll 中也存在同样的问题。如果我可以分配 DTD 或执行 XSL 翻译来说服 Apple API 我的数据是我希望作为 NSData 返回的 Base64 字符数据,那就太好了。有人有这方面的代码吗?我确实在DTD中发现了xs:base64Binary标签的非规范使用,但我还没有尝试过Apple ID是否接受它。太多的工作只是为了看看它是否有效。
I will most likely end up answering my own question, because I need this bug fixed before I can go on, but then it is here for documentation purposes. NOTE: I am not using the SAX parser like every other question/answer I found.
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");
It should be noted that within the same function, the NSAssert at the end DOES NOT FIRE.
However after sending the xml through to the server, I get a NSString as return type.
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]);
The output is ...
2012-01-05 13:58:29.336 auth[18773:1f03] Why am I getting a __NSCFString returned from a CDATA section!?
Any help is appreciated, thanks.
===== UPDATE =====
The question is still open. Best solution that I found was to find an external base64 encryption solution to encode the NSMutableData into a NSString and then use setStringValue. Then I use the decrypt of base64 to decrypt the string returned by stringValue, avoiding the problem.
To be exact, I used the - (NSString *)base64Encoding from http://www.cocoadev.com/index.pl?BaseSixtyFour to jimmy rig it for now, but I will most likely implement raw writing of NSData bytes into BSON format and see if that will cut it. I read that base64 gives about a 33% increase in data size and I think I want to avoid that if possible.
Solutions to above are still very welcome.
=== MORE UPDATE ===
Some options I have looked into are DTD and XSL. The same issue was in MSXML.dll a long time ago. It would be just fine if I could assign a DTD or do an XSL translation to convince the Apple API that my data is base64 character data that I want returned as NSData. Does anyone have code for this? I did find the non-normative use of the xs:base64Binary tag in DTD, but I haven't tried if the Apple ID accepts it. Too much work just to see if it works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
CDATA 部分不允许您传递二进制数据。它们专门用于标记必须仅解释为字符数据而不是标记的内容部分。 CDATA 节点内的数据和文本节点内的数据之间没有语义差异。如果需要对二进制数据进行编码,则需要将其转换为 UTF-8 兼容的内容。 Base64 是典型的选择。
以下是维基百科页面中的相关段落:
所有这一切的最终结果是,虽然
NSXMLNode
API 可能接受NSData
作为输入,但它们没有义务为您提供NSData
code> 解析外部文档后。事实上,由于 CDATA 部分的内容是字符数据,因此NSXMLNode
返回NSString
更为正确(正如您所说,它正在这样做)。CDATA sections are not intended to allow you to pass binary data. They're specifically intended to mark a section of content that must be interpreted only as character data rather than markup. There is no semantic difference between data inside a CDATA node and data inside a text node. If you need to encode binary data, you need to convert it to something UTF-8-compatible. Base64 is the typical choice.
Here's a relevant passage from the wikipedia page:
The end result of all this is that while the
NSXMLNode
APIs may accept anNSData
as input, they're under no obligation to provide you with anNSData
after parsing an external document. In fact, since the contents of a CDATA section are character data, it's more correct forNSXMLNode
to return anNSString
(which, as you said, it's doing).