NSXMLParser и BOM байты - PullRequest
       29

NSXMLParser и BOM байты

0 голосов
/ 14 января 2010

Я получаю свой XML-файл в результате запроса php с какого-либо сервера. Когда я печатаю полученные данные в консоль, я получаю хорошо структурированный XML-файл. Когда я пытаюсь разобрать его с помощью NSXMLParser, он возвращает NSXMLParserErrorDomain с кодом 4 - пустой документ. Я видел, что xmls, который не может анализировать, имеет последовательность BOM (метка порядка байтов) сразу после закрытия метки>> заголовка xml. Вопрос в том, как избавиться от последовательности спецификации. Я попытался создать строку с такими байтами спецификации:

    const   UInt8 bom[3] = {0xEF, 0xBB, 0xBF};
NSString    *bomString = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bom length:3] encoding:NSUTF8StringEncoding];
NSString    *noBOMString = [theResult stringByReplacingOccurrencesOfString:bomString withString:@" "];

но по какой-то причине это не работает. Есть xmls, которые имеют эту последовательность после корневого элемента. В этом случае NSXMLParser успешно анализирует xml. Safari игнорирует этих персонажей. Итак, отладчик Xcode. Пожалуйста, помогите!

Спасибо

Нав

Ответы [ 3 ]

0 голосов
/ 15 января 2010

Ну, может быть, это не лучший способ избавиться от байтов спецификации, но он работает. Для тех, кто провел такие часы, как я, пытаясь заставить NSXMLParser проглотить спецификации: Учитывая, что вы получаете ваши данные через NSURLConnection и сохраняете их в NSMutableData * webData.

    const char bom[3] = {0xEF, 0xBB, 0xBF};

char *data = [webData mutableBytes];
char *cp = data, *pp;
long lessBom = 0;
do {
    cp = strstr((const char *)cp, (const char *)bom);
    if (cp) {
        pp = cp;
        cp += 3;
        memcpy(pp, cp, strlen(cp));
        lessBom += 3;
    }
} while (cp != NULL);

NSMutableData   *newData = [[NSMutableData alloc] initWithBytes:data length:webData.length - lessBom];

Затем вы создаете свой парсер с новыми данными, и он ПРОСТО РАБОТАЕТ! Я буду рад получить любые комментарии / улучшения к этому коду

0 голосов
/ 16 января 2010

Я пытался создать строку с такими байтами спецификации:

const   UInt8 bom[3] = {0xEF, 0xBB, 0xBF};
NSString    *bomString = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bom length:3] encoding:NSUTF8StringEncoding];
NSString    *noBOMString = [theResult stringByReplacingOccurrencesOfString:bomString withString:@" "];

но по какой-то причине это не работает.

Убедитесь, что вы указали правильную кодировку при создании экземпляра noBOMString. Если данные документа были UTF-8, убедитесь, что вы создали экземпляр строки как UTF-8. Аналогично, если данные были UTF-16, убедитесь, что вы создали экземпляр строки как UTF-16.

Если вы передадите неправильную кодировку, либо строка не будет создаваться вообще (я полагаю, это не ваша проблема), либо некоторые символы будут неправильными. Спецификация может быть одной из следующих: если ввод UTF-8 и вы интерпретируете его как MacRoman или ISOLatin1, он будет отображаться в строке как три отдельных символа. Эти три отдельных символа не будут сравниваться равными одному символу, являющемуся спецификацией.

0 голосов
/ 14 января 2010

Я не уверен, что это проблема. У меня был очень похожий опыт, когда файл был закодирован как UTF-8, но заголовок xml утверждал, что это UTF-16.

В результате несоответствия мне не удалось проанализировать его с той же ошибкой, что и у вас. Однако, изменение заголовка xml с UTF-16 на UTF-8 решило мою проблему для меня.

Возможно, у вас возникла похожая проблема.

...