NSXMLParser rss edition NSXMLParserInvalidCharacterError - PullRequest
3 голосов
/ 30 июля 2009

NSXMLParserInvalidCharacterError # 9

Это ошибка, которую я получаю, когда сталкиваюсь со странным символом (например, кавычки, скопированные и вставленные из слова в веб-форму, которые заканчиваются в ленте).Канал, который я использую, не дает кодировки, и у меня нет надежды заставить их изменить это.Это все, что я получаю в заголовке:

<? Xml version = "1.0"?>

Что я могу сделать с недопустимыми символами при разборе каналов?Нужно ли сканировать данные до разбора?Что-то мне не хватает в API?Кто-нибудь имел дело с этим вопросом?

Ответы [ 3 ]

7 голосов
/ 03 августа 2009
NSString *dataString = [[[NSString alloc] initWithData:webData encoding:NSASCIIStringEncoding] autorelease];

NSData *data = [dataString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];

Исправлены мои проблемы ...

1 голос
/ 20 августа 2009

Метод NSString -initWithData:encoding: возвращает nil в случае сбоя, поэтому вы можете попробовать одну кодировку за другой, пока не найдете ту, которая преобразуется. Это не гарантирует правильного преобразования всех символов, но если ваш источник каналов не отправляет вам правильно закодированный XML, вам, вероятно, придется с этим смириться.

Основная идея:

// try the most likely encoding
NSString xmlString = [[NSString alloc] initWithData:xmlData 
                                           encoding:NSUTF8StringEncoding];

if (xmlString == nil) {
  // try the next likely encoding
  xmlString = [[NSString alloc] initWithData:xmlData 
                                     encoding:NSWindowsCP1252StringEncoding];
}

if (xmlString == nil) {
  // etc...
}

Чтобы быть универсальным и устойчивым, вы можете сделать следующее до успеха:

1.) Попробуйте кодировку, указанную в заголовке Content-Type ответа HTTP (если есть)

2.) Проверьте начало данных ответа для метки порядка байтов и, если найдено, попробуйте указанную кодировку

3.) Посмотрите на первые два байта; если вы найдете символ пробела или '<' в паре с нулевым / нулевым символом, попробуйте UTF-16 (аналогично, вы можете проверить первые четыре байта, чтобы увидеть, есть ли у вас UTF-32) </p>

4.) Отсканируйте начало данных в поисках инструкции обработки <?xml ... ?> и найдите внутри нее encoding='something'; попробуйте эту кодировку.

5.) Попробуйте некоторые распространенные кодировки. Обязательно проверьте Windows Latin-1, Mac Roman и ISO Latin-1, если ваш источник данных на английском языке.

6.) Если ничего из вышеперечисленного не работает, вы можете попробовать удалить все байты, превышающие 127 (или заменить '?' Или другой символ ASCII), и преобразовать данные, используя кодировку ASCII.

Если к этому моменту у вас нет строки NSSt, вы должны потерпеть неудачу. Если у вас есть строка NSString, вы должны искать объявление encoding в инструкции обработки <?xml ... ?> (если вы этого еще не сделали на шаге 4). Если он есть, вы должны преобразовать NSString обратно в NSData, используя эту кодировку; если его там нет, вам следует конвертировать обратно, используя кодировку UTF-8.

Кроме того, функции CFStringConvertIANACharSetNameToEncoding() и CFStringConvertEncodingToNSStringEncoding() могут помочь получить кодировку NSStringEncoding, которая идет вместе с именем кодировки из заголовка Content-Type или инструкции обработки <?xml ... ?>.

0 голосов
/ 16 апреля 2012

Вы также можете удалить эту строку кодирования из xml следующим образом:

int length = str.length >100 ? 100:str.length;
NSString*mystr= [str stringByReplacingOccurrencesOfString:@"encoding=\".*?\"" 
                        withString:@""
                        options:NSRegularExpressionSearch 
                        range:NSMakeRange(0, length)];
...