Чтение NSData из раздела XML CData вместо NSString - PullRequest
0 голосов
/ 05 января 2012

Скорее всего, я в конечном итоге отвечу на свой вопрос, потому что мне нужно исправить эту ошибку, прежде чем я смогу продолжить, но тогда это здесь для целей документации. ПРИМЕЧАНИЕ. Я не использую синтаксический анализатор 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, чтобы избежать проблемы.

Точнее говоря, я использовал - (NSString *) base64Encoding от http://www.cocoadev.com/index.pl?BaseSixtyFour, чтобы пока дразнить его, но я, скорее всего, реализую необработанную запись байтов NSData в формат BSON и посмотрю, будет ли это сокращено Это. Я прочитал, что base64 дает увеличение объема данных примерно на 33%, и я думаю, что хочу избежать этого, если это возможно.

Решения выше все еще очень приветствуются.

=== БОЛЬШЕ ОБНОВЛЕНИЙ ===

Некоторые опции, которые я рассмотрел, это DTD и XSL. Та же проблема была в MSXML.dll давным-давно. Было бы хорошо, если бы я мог назначить DTD или выполнить перевод XSL, чтобы убедить Apple API, что мои данные - это символьные данные base64, которые я хочу вернуть как NSData. У кого-нибудь есть код для этого? Я нашел ненормативное использование тега xs: base64Binary в DTD, но я не пробовал, принимает ли его Apple ID. Слишком много работы, чтобы посмотреть, работает ли она.

1 Ответ

1 голос
/ 06 января 2012

CDATA-разделы не предназначены для передачи двоичных данных. Они специально предназначены для маркировки раздела контента, который должен интерпретироваться только как символьные данные , а не как разметка. Нет семантической разницы между данными внутри узла CDATA и данными внутри текстового узла. Если вам нужно кодировать двоичные данные, вам нужно преобразовать их во что-нибудь, совместимое с UTF-8. Base64 - типичный выбор.

Вот соответствующий отрывок со страницы википедии :

Новые авторы XML-документов часто неправильно понимают цель раздела CDATA, ошибочно полагая, что его цель - «защитить» данные от обработки как обычных символьных данных во время обработки. Некоторые API-интерфейсы для работы с XML-документами предлагают варианты независимого доступа к разделам CDATA, но такие параметры существуют сверх обычных требований систем обработки XML и по-прежнему не меняют неявный смысл данных. Символьные данные - это символьные данные, независимо от того, выражены они через секцию CDATA или обычную разметку.

Конечным результатом всего этого является то, что хотя API NSXMLNode могут принимать NSData в качестве входных данных, они не обязаны предоставлять вам NSData после анализа внешнего документа. Фактически, поскольку содержимое раздела CDATA является символьными данными, для NSXMLNode правильнее будет возвращать NSString (что, как вы сказали, он делает).

...