从 XML CData 部分而不是 NSString 读取 NSData

发布于 2024-12-24 18:41:02 字数 1549 浏览 1 评论 0原文

我很可能最终会回答我自己的问题,因为我需要先修复这个错误,然后才能继续,但它是出于文档目的而放在这里的。注意:我没有像我发现的其他问题/答案那样使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

弱骨蛰伏 2024-12-31 18:41:02

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

以下是维基百科页面中的相关段落:

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

所有这一切的最终结果是,虽然 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:

New authors of XML documents often misunderstand the purpose of a CDATA section, mistakenly believing that its purpose is to "protect" data from being treated as ordinary character data during processing. Some APIs for working with XML documents do offer options for independent access to CDATA sections, but such options exist above and beyond the normal requirements of XML processing systems, and still do not change the implicit meaning of the data. Character data is character data, regardless of whether it is expressed via a CDATA section or ordinary markup.

The end result of all this is that while the NSXMLNode APIs may accept an NSData as input, they're under no obligation to provide you with an NSData after parsing an external document. In fact, since the contents of a CDATA section are character data, it's more correct for NSXMLNode to return an NSString (which, as you said, it's doing).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文