HTML в кодировке iOS для NSString? - PullRequest
       0

HTML в кодировке iOS для NSString?

2 голосов
/ 29 сентября 2011

Я в процессе портирования Android-приложения на iOS, и я столкнулся с небольшим препятствием. Я извлекаю данные в кодировке HTML с веб-страницы, но некоторые данные представлены в Юникоде для отображения иностранных символов ... поэтому символы на русском языке (Лети за мной) будут проанализированы как "Лет..."

В Android я смог обойти это, вызвав HTML.fromHTML (). Есть ли что-нибудь подобное в iOS?

Ответы [ 3 ]

6 голосов
/ 30 сентября 2011

Довольно легко написать свой собственный декодер HTML-сущностей.Просто отсканируйте строку в поисках &, прочитайте до следующего; затем интерпретируйте результаты.Если это «amp», «lt», «gt» или «quot», замените его соответствующим символом.Если это начинается с #, это числовой объект.Если за символом «#» следует символ «x», остальное следует считать шестнадцатеричным, в противном случае - десятичным.Прочитайте число, а затем вставьте символ в вашу строку (если вы пишете в NSMutableString, вы можете использовать [str appendFormat:@"%C", thechar]. NSScanner, что может сделать сканирование строки довольно простым, тем более что он уже знает, как читать шестнадцатеричные числацифры.

Я только что создал функцию, которая должна сделать это для вас. Обратите внимание, я на самом деле не проверял это, поэтому вы должны пройти через все шаги:

- (NSString *)stringByDecodingHTMLEntitiesInString:(NSString *)input {
    NSMutableString *results = [NSMutableString string];
    NSScanner *scanner = [NSScanner scannerWithString:input];
    [scanner setCharactersToBeSkipped:nil];
    while (![scanner isAtEnd]) {
        NSString *temp;
        if ([scanner scanUpToString:@"&" intoString:&temp]) {
            [results appendString:temp];
        }
        if ([scanner scanString:@"&" intoString:NULL]) {
            BOOL valid = YES;
            unsigned c = 0;
            NSUInteger savedLocation = [scanner scanLocation];
            if ([scanner scanString:@"#" intoString:NULL]) {
                // it's a numeric entity
                if ([scanner scanString:@"x" intoString:NULL]) {
                    // hexadecimal
                    unsigned int value;
                    if ([scanner scanHexInt:&value]) {
                        c = value;
                    } else {
                        valid = NO;
                    }
                } else {
                    // decimal
                    int value;
                    if ([scanner scanInt:&value] && value >= 0) {
                        c = value;
                    } else {
                        valid = NO;
                    }
                }
                if (![scanner scanString:@";" intoString:NULL]) {
                    // not ;-terminated, bail out and emit the whole entity
                    valid = NO;
                }
            } else {
                if (![scanner scanUpToString:@";" intoString:&temp]) {
                    // &; is not a valid entity
                    valid = NO;
                } else if (![scanner scanString:@";" intoString:NULL]) {
                    // there was no trailing ;
                    valid = NO;
                } else if ([temp isEqualToString:@"amp"]) {
                    c = '&';
                } else if ([temp isEqualToString:@"quot"]) {
                    c = '"';
                } else if ([temp isEqualToString:@"lt"]) {
                    c = '<';
                } else if ([temp isEqualToString:@"gt"]) {
                    c = '>';
                } else {
                    // unknown entity
                    valid = NO;
                }
            }
            if (!valid) {
                // we errored, just emit the whole thing raw
                [results appendString:[input substringWithRange:NSMakeRange(savedLocation, [scanner scanLocation]-savedLocation)]];
            } else {
                [results appendFormat:@"%C", c];
            }
        }
    }
    return results;
}
2 голосов
/ 30 сентября 2011

Конструкция &#(number); в HTML (и XML) называется ссылкой на символ. Это не зависит от Unicode, за исключением того, что все символы в HTML определены в терминах Unicode, независимо от того, включены ли они дословно или закодированы как ссылка на символ или сущность. (Ссылки на сущности являются именованными, которые выглядят как &eacute; или &amp;, и если вы просматриваете HTML-страницу, вам, безусловно, придется иметь дело и с ними.)

В стандартной библиотеке нет функции для декодирования ссылок на символы или объекты. См. этот вопрос о подходах к декодированию текстового содержимого HTML. Если у вас есть только ссылки на символы и стандартные объекты XML, такие как &amp;, вы можете использовать NSXMLParser для анализа <element> + yourstring + </element>, но это не будет обрабатывать специфичные для HTML объекты, такие как &eacute; .

Как правило, очистку экрана лучше всего выполнять с помощью правильного анализатора HTML, а не с помощью взлома строк. Это преобразует весь текстовый контент в текстовые узлы, конвертируя ссылки на символы и сущности по мере необходимости. Однако, опять же, в стандартной библиотеке нет анализатора HTML. Если целевая страница имеет правильный формат XHTML, вы можете снова использовать NSXMLParser. В противном случае вы можете попробовать libxml2, который предлагает анализатор HTML, а также XML. См. этот вопрос для некоторого фона.

0 голосов
/ 30 сентября 2011

если вы получаете данные с веб-сайта, у вас будет NS(Mutable)Data -объект в качестве буфера приема.Вам просто нужно преобразовать это NSData в NSString через:
NSString *myString = [[NSString alloc] initWithData:myRecvData usingEncoding:NSUnicodeStringEncoding]
, если ваш сервер отправляет в Unicode.Если ваш сервер отправляет utf-8 или другой, вам нужно также настроить кодирование строки в вашем принимающем коде.

здесь список всех поддерживаемых типов кодирования строки

edit: взгляните на это so-thread .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...