Декодирование символов HTML в Objective-C / Cocoa Touch

Прежде всего, я нашел это:Цель C HTML escape / unescape, но это не работает для меня.

Мои закодированные символы (взятые из ленты RSS, кстати) выглядят так:&

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

 Sanju23 мар. 2017 г., 07:15
 johne16 февр. 2010 г., 06:48
Этот комментарий спустя шесть месяцев после первоначального вопроса, так что это больше для тех, кто наткнулся на этот вопрос, ища ответ и решение. Совсем недавно возник очень похожий вопрос, на который я ответилstackoverflow.com/questions/2254862/…  Он использует RegexKitLite и Blocks для поиска и замены&#...; в строке с ее эквивалентным символом.
 kennytm03 мар. 2010 г., 15:46
Это десятичное число. Шестнадцатеричный8.
 Peter Hosey03 мар. 2010 г., 15:45
Что конкретно не работает & # x201C ;? Я не вижу в этом вопросе ничего, что не являлось бы копией этого более раннего вопроса.
 Peter Hosey03 мар. 2010 г., 18:34
Разница между десятичной и шестнадцатеричной состоит в том, что десятичная дробь - это base-10, тогда как шестнадцатеричная - это base-16. & # X201C; 38 & # x201D; это разные числа в каждой базе; в базе 10 это 3 '# 10 x 8; 10 x 8; 1 = тридцать восемь, тогда как в базе 16 это 3' # 16 x 8; 16 + 8 & xD7; 1 = пятьдесят шесть. Высшие цифры - это (кратные) высшие степени основания; самая низкая целая цифра является базовой0 (= 1), the next higher digit is base1 (= основание), следующий - основание ** 2 (= основание * основание) и т. Д. Это экспонента на работе.

Ответы на вопрос(13)

Никто, кажется, не упоминает один из самых простых вариантов:Google Toolbox для Mac
(Несмотря на название, это работает на iOS тоже.)

https://github.com/google/google-toolbox-for-mac/blob/master/Foundation/GTMNSString%2BHTML.h

/// Get a string where internal characters that are escaped for HTML are unescaped 
//
///  For example, '&' becomes '&'
///  Handles   and 2 cases as well
///
//  Returns:
//    Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;

И мне пришлось включить в проект только три файла: заголовок, реализацию иGTMDefines.h.

 15 июн. 2012 г., 13:41
отлично .. сработало для меня :)
 08 нояб. 2011 г., 21:34
Я решил включить только эти три файла, поэтому мне нужно было сделать это, чтобы сделать его совместимым с arc:code.google.com/p/google-toolbox-for-mac/wiki/ARC_Compatibility
 26 авг. 2011 г., 08:59
@ borut-t [myString gtm_stringByUnescapingFromHTML]
 17 янв. 2013 г., 14:04
Я должен сказать, что это самое простое и легкое решение на сегодняшний день
 26 авг. 2011 г., 08:29
Я включил эти три сценария, но как я могу использовать его сейчас?

На самом деле замечательная среда MWFeedParser Майкла Водопада (см. Его ответ) была разветвлена rmchaara, которая обновила его при поддержке ARC!

Вы можете найти его в GithubВот

Это действительно прекрасно работает, я использовал метод stringByDecodingHTMLEntities и работает без нареканий.

 24 окт. 2013 г., 15:05
Это решает проблемы ARC - но вводит некоторые предупреждения. Я думаю, что их можно игнорировать?

Swift 3 version of Jugale's answer

extension String {
    static private let mappings = ["&quot;" : "\"","&amp;" : "&", "&lt;" : "<", "&gt;" : ">","&nbsp;" : " ","&iexcl;" : "¡","&cent;" : "¢","&pound;" : " £","&curren;" : "¤","&yen;" : "¥","&brvbar;" : "¦","&sect;" : "§","&uml;" : "¨","&copy;" : "©","&ordf;" : " ª","&laquo" : "«","&not" : "¬","&reg" : "®","&macr" : "¯","&deg" : "°","&plusmn" : "±","&sup2; " : "²","&sup3" : "³","&acute" : "´","&micro" : "µ","&para" : "¶","&middot" : "·","&cedil" : "¸","&sup1" : "¹","&ordm" : "º","&raquo" : "»&","frac14" : "¼","&frac12" : "½","&frac34" : "¾","&iquest" : "¿","&times" : "×","&divide" : "÷","&ETH" : "Ð","&eth" : "ð","&THORN" : "Þ","&thorn" : "þ","&AElig" : "Æ","&aelig" : "æ","&OElig" : "Œ","&oelig" : "œ","&Aring" : "Å","&Oslash" : "Ø","&Ccedil" : "Ç","&ccedil" : "ç","&szlig" : "ß","&Ntilde;" : "Ñ","&ntilde;":"ñ",]

    func stringByDecodingXMLEntities() -> String {

        guard let _ = self.range(of: "&", options: [.literal]) else {
            return self
        }

        var result = ""

        let scanner = Scanner(string: self)
        scanner.charactersToBeSkipped = nil

        let boundaryCharacterSet = CharacterSet(charactersIn: " \t\n\r;")

        repeat {
            var nonEntityString: NSString? = nil

            if scanner.scanUpTo("&", into: &nonEntityString) {
                if let s = nonEntityString as? String {
                    result.append(s)
                }
            }

            if scanner.isAtEnd {
                break
            }

            var didBreak = false
            for (k,v) in String.mappings {
                if scanner.scanString(k, into: nil) {
                    result.append(v)
                    didBreak = true
                    break
                }
            }

            if !didBreak {

                if scanner.scanString("&#", into: nil) {

                    var gotNumber = false
                    var charCodeUInt: UInt32 = 0
                    var charCodeInt: Int32 = -1
                    var xForHex: NSString? = nil

                    if scanner.scanString("x", into: &xForHex) {
                        gotNumber = scanner.scanHexInt32(&charCodeUInt)
                    }
                    else {
                        gotNumber = scanner.scanInt32(&charCodeInt)
                    }

                    if gotNumber {
                        let newChar = String(format: "%C", (charCodeInt > -1) ? charCodeInt : charCodeUInt)
                        result.append(newChar)
                        scanner.scanString(";", into: nil)
                    }
                    else {
                        var unknownEntity: NSString? = nil
                        scanner.scanUpToCharacters(from: boundaryCharacterSet, into: &unknownEntity)
                        let h = xForHex ?? ""
                        let u = unknownEntity ?? ""
                        result.append("&#\(h)\(u)")
                    }
                }
                else {
                    scanner.scanString("&", into: nil)
                    result.append("&")
                }
            }

        } while (!scanner.isAtEnd)

        return result
    }
}

Вот Swift-версияОтвет Уолти Йенга:

extension String {
    static private let mappings = ["&quot;" : "\"","&amp;" : "&", "&lt;" : "<", "&gt;" : ">","&nbsp;" : " ","&iexcl;" : "¡","&cent;" : "¢","&pound;" : " £","&curren;" : "¤","&yen;" : "¥","&brvbar;" : "¦","&sect;" : "§","&uml;" : "¨","&copy;" : "©","&ordf;" : " ª","&laquo" : "«","&not" : "¬","&reg" : "®","&macr" : "¯","&deg" : "°","&plusmn" : "±","&sup2; " : "²","&sup3" : "³","&acute" : "´","&micro" : "µ","&para" : "¶","&middot" : "·","&cedil" : "¸","&sup1" : "¹","&ordm" : "º","&raquo" : "»&","frac14" : "¼","&frac12" : "½","&frac34" : "¾","&iquest" : "¿","&times" : "×","&divide" : "÷","&ETH" : "Ð","&eth" : "ð","&THORN" : "Þ","&thorn" : "þ","&AElig" : "Æ","&aelig" : "æ","&OElig" : "Œ","&oelig" : "œ","&Aring" : "Å","&Oslash" : "Ø","&Ccedil" : "Ç","&ccedil" : "ç","&szlig" : "ß","&Ntilde;" : "Ñ","&ntilde;":"ñ",]

    func stringByDecodingXMLEntities() -> String {

        guard let _ = self.rangeOfString("&", options: [.LiteralSearch]) else {
            return self
        }

        var result = ""

        let scanner = NSScanner(string: self)
        scanner.charactersToBeSkipped = nil

        let boundaryCharacterSet = NSCharacterSet(charactersInString: " \t\n\r;")

        repeat {
            var nonEntityString: NSString? = nil

            if scanner.scanUpToString("&", intoString: &nonEntityString) {
                if let s = nonEntityString as? String {
                    result.appendContentsOf(s)
                }
            }

            if scanner.atEnd {
                break
            }

            var didBreak = false
            for (k,v) in String.mappings {
                if scanner.scanString(k, intoString: nil) {
                    result.appendContentsOf(v)
                    didBreak = true
                    break
                }
            }

            if !didBreak {

                if ,scanner.scanString("&#", intoString: nil) {

                    var gotNumber = false
                    var charCodeUInt: UInt32 = 0
                    var charCodeInt: Int32 = -1
                    var xForHex: NSString? = nil

                    if scanner.scanString("x", intoString: &xForHex) {
                        gotNumber = scanner.scanHexInt(&charCodeUInt)
                    }
                    else {
                        gotNumber = scanner.scanInt(&charCodeInt)
                    }

                    if gotNumber {
                        let newChar = String(format: "%C", (charCodeInt > -1) ? charCodeInt : charCodeUInt)
                        result.appendContentsOf(newChar)
                        scanner.scanString(";", intoString: nil)
                    }
                    else {
                        var unknownEntity: NSString? = nil
                        scanner.scanUpToCharactersFromSet(boundaryCharacterSet, intoString: &unknownEntity)
                        let h = xForHex ?? ""
                        let u = unknownEntity ?? ""
                        result.appendContentsOf("&#\(h)\(u)")
                    }
                }
                else {
                    scanner.scanString("&", intoString: nil)
                    result.appendContentsOf("&")
                }
            }

        } while (!scanner.atEnd)

        return result
    }
}

Даниэль в основном очень хорош, и я исправил там несколько проблем:

removed the skipping character for NSSCanner (otherwise spaces between two continuous entities would be ignored

[scanner setCharactersToBeSkipped:nil];

fixed the parsing when there are isolated '&' symbols (I am not sure what is the 'correct' output for this, I just compared it against firefox):

например

    &#ABC DF & B&#39;  & C&#39; Items (288)

вот модифицированный код:

- (NSString *)stringByDecodingXMLEntities {
    NSUInteger myLength = [self length];
    NSUInteger am,pIndex = [self rangeOfString:@"&" options:NSLiteralSearch].location;

    // Short-circuit if there are no ampersands.
    if (ampIndex == NSNotFound) {
        return self;
    }
    // Make result string with some extra capacity.
    NSMutableString *result = [NSMutableString stringWithCapacity:(myLength * 1.25)];

    // First iteration doesn't need to scan to & since we did that already, but for code simplicity's sake we'll do it again with the scanner.
    NSScanner *scanner = [NSScanner scannerWithString:self];

    [scanner setCharactersToBeSkipped:nil];

    NSCharacterSet *boundaryCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" \t\n\r;"];

    do {
        // Scan up to the next entity or the end of the string.
        NSString *nonEntityString;
        if ([scanner scanUpToString:@"&" intoString:&nonEntityString]) {
            [result appendString:nonEntityString];
        }
        if ([scanner isAtEnd]) {
            goto finish;
        }
        // Scan either a HTML or numeric character entity reference.
        if ([scanner scanString:@"&amp;" intoString:NULL])
            [result appendString:@"&"];
        else if ([scanner scanString:@"&apos;" intoString:NULL])
            [result appendString:@"'"];
        else if ([scanner scanString:@"&quot;" intoString:NULL])
            [result appendString:@"\""];
        else if ([scanner scanString:@"&lt;" intoString:NULL])
            [result appendString:@"<"];
        else if ([scanner scanString:@"&gt;" intoString:NULL])
            [result appendString:@">"];
        else if ([scanner scanString:@"&#" intoString:NULL]) {
            BOOL gotNumber;
            unsigned charCode;
            NSString *xForHex = @"";

            // Is it hex or decimal?
            if ([scanner scanString:@"x" intoString:&xForHex]) {
                gotNumber = [scanner scanHexInt:&charCode];
            }
            else {
                gotNumber = [scanner scanInt:(int*)&charCode];
            }

            if (gotNumber) {
                [result appendFormat:@"%C", (unichar)charCode];

                [scanner scanString:@";" intoString:NULL];
            }
            else {
                NSString *unknownEntity = @"";

                [scanner scanUpToCharactersFromSet:boundaryCharacterSet intoString:&unknownEntity];


              ,  [result appendFormat:@"&#%@%@", xForHex, unknownEntity];

                //[scanner scanUpToString:@";" intoString:&unknownEntity];
                //[result appendFormat:@"&#%@%@;", xForHex, unknownEntity];
                NSLog(@"Expected numeric character entity but got &#%@%@;", xForHex, unknownEntity);

            }

        }
        else {
            NSString *amp;

            [scanner scanString:@"&" intoString:&amp];  //an isolated & symbol
            [result appendString:amp];

            /*
            NSString *unknownEntity = @"";
            [scanner scanUpToString:@";" intoString:&unknownEntity];
            NSString *semicolon = @"";
            [scanner scanString:@";" intoString:&semicolon];
            [result appendFormat:@"%@%@", unknownEntity, semicolon];
            NSLog(@"Unsupported XML character entity %@%@", unknownEntity, semicolon);
             */
        }

    }
    while (![scanner isAtEnd]);

finish:
    return result;
}
 21 мар. 2013 г., 19:42
Я бы тебя дважды одобрил, если бы мог
 11 мая 2010 г., 18:55
Отлично, работает отлично! Приятные изменения!
 03 авг. 2012 г., 15:06
Это сработало отлично. К сожалению, код ответа с наивысшей оценкой больше не работает из-за проблем ARC, но это работает.
 25 нояб. 2010 г., 16:24
Это должно быть однозначным ответом на вопрос !! Спасибо!
 04 февр. 2013 г., 14:56
@TedKulp это работает просто отлично, вам просто нужно отключить ARC для каждого файла.stackoverflow.com/questions/6646052/…

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

+ (NSString*) decodeHtmlUnicodeCharactersToString:(NSString*)str
{
    NSMutableString* string = [[NSMutableString alloc] initWithString:str];  // #&39; replace with '
    NSString* unicodeStr = nil;
    NSString* replaceStr = nil;
    int counter = -1;

    for(int i = 0; i < [string length]; ++i)
    {
        unichar char1 = [string characterAtIndex:i];    
        for (int k = i + 1; k < [string length] - 1; ++k)
        {
            unichar char2 = [string characterAtIndex:k];    

            if (char1 == '&'  && char2 == '#' ) 
            {   
                ++counter;
                unicodeStr = [string substringWithRange:NSMakeRange(i + 2 , 2)];    
                // read integer value i.e, 39
                replaceStr = [string substringWithRange:NSMakeRange (i, 5)];     //     #&39;
                [string replaceCharactersInRange: [string rangeOfString:replaceStr] withString:[NSString stringWithFormat:@"%c",[unicodeStr intValue]]];
                break;
            }
        }
    }
    [string autorelease];

    if (counter > 1)
        return  [self decodeHtmlUnicodeCharactersToString:string]; 
    else
        return string;
}
Решение Вопроса

Те называютсяСсылки на персонажа, Когда они принимают форму&#<number>; они называютсяnumeric entity references, По существу, это строковое представление байта, которое должно быть заменено. В случае&#038;, он представляет символ со значением 38 в схеме кодирования символов ISO-8859-1, которая является&.

Причина, по которой амперсанд должен быть закодирован в RSS, состоит в том, что он является зарезервированным специальным символом.

Вам нужно разобрать строку и заменить сущности байтом, соответствующим значению между&# а также;, Я не знаю каких-либо замечательных способов сделать это в задаче C, ноэтот вопрос переполнения стека может быть какой-то помощи

Изменить: так как ответ на это около двух лет назад, есть несколько замечательных решений; см. ответ @Michael Waterfall 'ниже.

 09 июл. 2009 г., 19:17
+1 Я как раз собирался представить точно такой же ответ (включая те же ссылки, не меньше!)
 09 июл. 2009 г., 20:17
& # x201C; По сути, это строковое представление байта, который должен быть заменен. & # x201D; Больше похоже на характер. Это текст, а не данные; после преобразования текста в данные символ может занимать несколько байтов в зависимости от символа и кодировки.
 23 апр. 2013 г., 09:57
а как насчет & amp; или & amp; копия; символы?
 treznik11 июл. 2009 г., 21:59
Спасибо за ответ. Вы сказали, что «он представляет символ со значением 38 в схеме кодировки символов ISO-8859-1, которая является & amp;". Вы уверены, что? У вас есть ссылка на таблицу символов этого типа? Потому что, насколько я помню, это была одиночная цитата.
 12 июл. 2009 г., 13:39
en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1 или просто введите & amp; # 038; в Google.

Это способ, которым я делаю это, используяRegexKitLite фреймворк:

-(NSString*) decodeHtmlUnicodeCharacters: (NSString*) html {
NSString* result = [html copy];
NSArray* matches = [result arrayOfCaptureComponentsMatchedByRegex: @"\\&#([\\d]+);"];

if (![matches count]) 
    return result;

for (int i=0; i<[matches count]; i++) {
    NSArray* array = [matches objectAtIndex: i];
    NSString* charCode = [array objectAtIndex: 1];
    int code = [charCode intValue];
    NSString* character = [NSString stringWithFormat:@"%C", code];
    result = [result stringByReplacingOccurrencesOfString: [array objectAtIndex: 0]
                                               withString: character];      
}   
return result;  

}

Надеюсь, это кому-нибудь поможет.

 03 мар. 2017 г., 10:23
У меня тоже работает, спасибо ....
 11 мая 2012 г., 07:59
Это работает ... Это потрясающе. Спасибо!

Начиная с iOS 7, вы можете самостоятельно декодировать символы HTML, используяNSAttributedString сNSHTMLTextDocumentType атрибут:

NSString *htmlString = @"&#63743; &amp; &#38; &lt; &gt; &trade; &copy; &hearts; &clubs; &spades; &diams;";
NSData *stringData = [htmlString dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary *options = @{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType};
NSAttributedString *decodedString;
decodedString = [[NSAttributedString alloc] initWithData:stringData
                                                 options:options
                                      documentAttributes:NULL
                                                   error:NULL];

Расшифрованная атрибутированная строка теперь будет отображаться как: & # xF8FF; & Амп; & Амп; & Lt; & GT; & # X2122; & # XA9; & # X2665; & # X2663; & # X2660; & # X2666 ;.

Note: Это будет работать только при вызове в главном потоке.

 07 янв. 2015 г., 05:02
Это должно произойти в главном потоке. Таким образом, вы, вероятно, не хотите делать это, если вам не нужно.
 09 дек. 2014 г., 22:31
Это сработало для декодирования сущности, но также испортило некодированную черту.
 30 нояб. 2014 г., 14:44
У меня не работает в iOS8 :(
 22 мая 2014 г., 12:59
лучший ответ, если вам не нужно поддерживать iOS 6 и старше
 20 окт. 2014 г., 10:11
нет, не самый лучший, если кто-то захочет закодировать его в потоке bg; O

Если у вас есть ссылка на символьную сущность в виде строки, например,@"2318"Вы можете извлечь перекодированную NSString с правильным символом Unicode, используяstrtoul;

NSString *unicodePoint = @"2318"
unichar iconChar = (unichar) strtoul(unicodePoint.UTF8String, NULL, 16);
NSString *recoded = [NSString stringWithFormat:@"%C", iconChar];
NSLog(@"recoded: %@", recoded");
// prints out "recoded: ⌘"

Я должен опубликовать это на GitHub или что-то. Это относится к категории NSString, используетNSScanner для реализации, и обрабатывает как шестнадцатеричные и десятичные числовые символьные объекты, так и обычные символические.

Кроме того, он обрабатывает искаженные строки (когда у вас есть & amp; за ним следует неверная последовательность символов) относительно изящно, что оказалось решающим в моемвыпущенное приложение который использует этот код.

- (NSString *)stringByDecodingXMLEntities {
    NSUInteger myLength = [self length];
    NSUInteger ampIndex = [self rangeOfString:@"&" options:NSLiteralSearch].location;

    // Short-circuit if there are no ampersands.
    if (ampIndex == NSNotFound) {
        return self;
    }
    // Make result string with some extra capacity.
    NSMutableString *result = [NSMutableString stringWithCapacity:(myLength * 1.25)];

    // First iteration doesn't need to scan to & since we did that already, but for code simplicity's sake we'll do it again with the scanner.
    NSScanner *scanner = [NSScanner scannerWithString:self];
    do {
        // Scan up to the next entity or the end of the string.
        NSString *nonEntityString;
        if ([scanner scanUpToString:@"&" intoString:&nonEntityString]) {
            [result appendString:nonEntityString];
        }
        if ([scanner isAtEnd]) {
            goto finish;
        }
        // Scan either a HTML or numeric character entity reference.
        if ([scanner scanString:@"&amp;" intoString:NULL])
            [result appendString:@"&"];
        else if ([scanner scanString:@"&apos;" intoString:NULL])
            [result appendString:@"'"];
        else if ([scanner scanString:@"&quot;" intoString:NULL])
            [result appendString:@"\""];
        else if ([scanner scanString:@"&lt;" intoString:NULL])
            [result appendString:@"<"];
        else if ([scanner scanString:@"&gt;" intoString:NULL])
            [result appendString:@">"];
        else if ([scanner scanString:@"&#" intoString:NULL]) {
            BOOL gotNumber;
            unsigned charCode;
            NSString *xForHex = @"";

            // Is it hex or decimal?
            if ([scanner scanString:@"x" intoString:&xForHex]) {
                gotNumber = [scanner scanHexInt:&charCode];
            }
            else {
                gotNumber = [scanner scanInt:(int*)&charCode];
            }
            if (gotNumber) {
                [result appendFormat:@"%C", charCode];
            }
            else {
                NSString *unknownEntity = @"";
                [scanner scanUpToString:@";" intoString:&unknownEntity];
                [result appendFormat:@"&#%@%@;", xForHex, unknownEntity];
                NSLog(@"Expected numeric character entity but got &#%@%@;", xForHex, unknownEntity);
            }
            [scanner scanString:@";" intoString:NULL];
        }
        else {
            NSString *unknownEntity = @"";
            [scanner scanUpToString:@";" intoString:&unknownEntity];
            NSString *semicolon = @"";
            [scanner scanString:@";" intoString:&semicolon];
            [result appendFormat:@"%@%@", unknownEntity, semicolon];
            NSLog(@"Unsupported XML character entity %@%@", unknownEntity, semicolon);
        }
    }
    while (![scanner isAtEnd]);

finish:
    return result;
}
 30 янв. 2016 г., 02:11
Вы должны избегать использованияgotoкак его ужасный стиль кода. Вы должны заменить линиюgoto finish; сbreak;.
 11 мая 2010 г., 18:56
Очень полезный кусок кода, однако у него есть пара проблем, которые были решены Уолти. Спасибо, что поделился!
 15 апр. 2012 г., 10:22
Знаете ли вы, как показать символы лямбда, му, ню, пи, расшифровав их XML-объекты, такие как & amp; micro; ... т. д. ????

Как будто вам нужно другое решение! Этот довольно простой и довольно эффективный:

@interface NSString (NSStringCategory)
- (NSString *) stringByReplacingISO8859Codes;
@end


@implementation NSString (NSStringCategory)
- (NSString *) stringByReplacingISO8859Codes
{
    NSString *dataString = self;
    do {
        //*** See if string contains &# prefix
        NSRange range = [dataString rangeOfString: @"&#" options: NSRegularExpressionSearch];
        if (range.location == NSNotFound) {
            break;
        }
        //*** Get the next three charaters after the prefix
        NSString *isoHex = [dataString substringWithRange: NSMakeRange(range.location + 2, 3)];
        //*** Create the full code for replacement
        NSString *isoString = [NSString stringWithFormat: @"&#%@;", isoHex];
        //*** Convert to decimal integer
        unsigned decimal = 0;
        NSScanner *scanner = [NSScanner scannerWithString: [NSString stringWithFormat: @"0%@", isoHex]];
        [scanner scanHexInt: &decimal];
        //*** Use decimal code to get unicode character
        NSString *unicode = [NSString stringWithFormat:@"%C", decimal];
        //*** Replace all occurences of this code in the string
        dataString = [dataString stringByReplacingOccurrencesOfString: isoString withString: unicode];
    } while (TRUE); //*** Loop until we hit the NSNotFound

    return dataString;
}
@end

Проверьте мойКатегория NSString для HTML, Вот доступные методы:

- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;
 08 июн. 2010 г., 08:41
Чувак, отличные функции. Ваш метод stringByDecodingXMLEntities сделал мой день! Спасибо!
 12 янв. 2011 г., 06:57
После нескольких часов поиска я знаю, что это единственный способ сделать это, который действительно работает. NSString просрочен для строкового метода, который может сделать это. Отлично сработано.
 27 июл. 2012 г., 00:46
Обновление кода для ARC было бы удобно. XCode выбрасывает тонну ошибок ARC и предупреждений при сборке.
 08 июн. 2010 г., 11:06
Нет проблем;) Рад, что вы нашли это полезным!
 08 нояб. 2011 г., 21:37
Я обнаружил (2) в лицензии Михаэля слишком ограничительную для моего случая использования, поэтому я использовал решение Никиты. Включение трех лицензированных Apache-2.0 файлов из набора инструментов Google прекрасно работает для меня.

Ваш ответ на вопрос