2012-01-05 3 views
0

Я, скорее всего, отвечу на свой вопрос, потому что мне нужно, чтобы эта ошибка была исправлена ​​до того, как я смогу продолжить, но тогда она здесь для целей документации. ПРИМЕЧАНИЕ. Я не использую парсер SAX, как и любой другой вопрос/ответ, который я нашел.Чтение NSData из раздела XML CData вместо NSString

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!? 

Любая помощь приветствуется, спасибо.

===== ===== UPDATE

вопрос остается открытым. Лучшим решением, которое я нашел, было найти внешнее решение для шифрования base64 для кодирования NSMutableData в NSString, а затем использовать setStringValue. Затем я использую расшифровку base64 для дешифрования строки, возвращаемой stringValue, избегая проблемы.

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

Решения, изложенные выше, по-прежнему очень приветствуются.

=== MORE UPDATE ===

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

ответ

1

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

Вот соответствующий отрывок из wikipedia page:

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

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

+0

Кевин, вы совершенно правы. Но то, что я ищу, - это способ получить NSData в любом случае. Я просмотрел DTD и XSL, возможно, используя тег xs: base64Binary, но я не вижу четкого способа сделать это. – PLG

+0

Как я уже говорил, когда я вытаскиваю данные из узла в той же функции (оператор NSAssert), данные возвращаются как NSData. Итак, я хочу добиться того же самого после передачи. – PLG

+0

@PLG: Когда вы устанавливаете 'objectValue' в' NSData', а затем немедленно вытаскиваете его, он даст вам то же самое 'NSData', которое вы ему дали. Но если вы проанализируете XML-документ и затем спросите узел о его 'objectValue', вы получите' NSString'. Я бы рекомендовал вместо этого использовать 'stringValue' и' setStringValue: 'и используя ваше собственное преобразование между' NSData' <-> 'NSString' (например, с base64 или некоторыми такими) –

Смежные вопросы