Decodifica dei caratteri HTML in Objective-C / Cocoa Touch


103

Prima di tutto, ho trovato questo: Objective C HTML escape / unescape , ma non funziona per me.

I miei caratteri codificati (provengono da un feed RSS, btw) hanno questo aspetto: &

Ho cercato in tutta la rete e ho trovato discussioni correlate, ma nessuna correzione per la mia particolare codifica, penso che siano chiamati caratteri esadecimali.


3
Questo commento è di sei mesi dopo la domanda originale, quindi è più per coloro che si imbattono in questa domanda alla ricerca di una risposta e di una soluzione. Una domanda molto simile si avvicinò proprio di recente che ho risposto stackoverflow.com/questions/2254862/... Esso utilizza RegexKitLite e blocchi di fare una ricerca e sostituzione del &#...;in una stringa con il suo carattere equivalente.
johne

Che cosa specificamente "non funziona"? Non vedo nulla in questa domanda che non sia un duplicato della domanda precedente.
Peter Hosey

È decimale. L'esadecimale è 8.
kennytm

La differenza tra decimale ed esadecimale è che il decimale è in base 10, mentre l'esadecimale è in base 16. "38" è un numero diverso in ciascuna base; in base 10 è 3 × 10 + 8 × 1 = trentotto, mentre in base 16 è 3 × 16 + 8 × 1 = cinquantasei. Le cifre più alte sono (multipli di) potenze superiori della base; la cifra intera più bassa è in base 0 (= 1), la cifra successiva più alta è in base 1 (= base), la successiva è in base ** 2 (= base * base), ecc. Questo è l'esponente al lavoro.
Peter Hosey

Risposte:


46

Questi sono chiamati riferimenti a entità di carattere . Quando assumono la forma di &#<number>;sono chiamati riferimenti a entità numeriche . Fondamentalmente, è una rappresentazione di stringa del byte che dovrebbe essere sostituito. Nel caso di &#038;, rappresenta il carattere con il valore 38 nello schema di codifica dei caratteri ISO-8859-1, che è &.

Il motivo per cui la e commerciale deve essere codificata in RSS è che è un carattere speciale riservato.

Quello che devi fare è analizzare la stringa e sostituire le entità con un byte corrispondente al valore compreso tra &#e ;. Non conosco nessun ottimo modo per farlo nell'obiettivo C, ma questa domanda di overflow dello stack potrebbe essere di qualche aiuto.

Modifica: da quando ho risposto a questa domanda circa due anni fa, ci sono alcune ottime soluzioni; vedi la risposta di @Michael Waterfall di seguito.


2
+1 Stavo per inviare la stessa identica risposta (inclusi gli stessi link, niente di meno!)
es

"Fondamentalmente, è una rappresentazione di stringa del byte che dovrebbe essere sostituito." Più come un personaggio. Questo è testo, non dati; dopo aver convertito il testo in dati, il carattere può occupare più byte, a seconda del carattere e della codifica.
Peter Hosey

Grazie per la risposta. Hai detto "rappresenta il carattere con il valore 38 nello schema di codifica dei caratteri ISO-8859-1, che è &". Sei sicuro di questo? Hai un collegamento a una tabella dei caratteri di questo tipo? Perché da quello che ricordo era un'unica citazione.
treznik

en.wikipedia.org/wiki/ISO/IEC_8859-1#ISO-8859-1 o digita semplicemente & # 038; in google.
Matt Bridges

e che dire di & amp; o & copy; simboli?
vokilam

162

Controlla la mia categoria NSString per HTML . Ecco i metodi disponibili:

- (NSString *)stringByConvertingHTMLToPlainText;
- (NSString *)stringByDecodingHTMLEntities;
- (NSString *)stringByEncodingHTMLEntities;
- (NSString *)stringWithNewLinesAsBRs;
- (NSString *)stringByRemovingNewLinesAndWhitespace;

3
Amico, funzioni eccellenti. Il tuo metodo stringByDecodingXMLEntities ha reso la mia giornata! Grazie!
Brian Moeskau

3
Nessun problema;) Sono contento che tu l'abbia trovato utile!
Michael Waterfall,

4
Dopo alcune ore di ricerca so che questo è l'unico modo per farlo che funziona davvero. NSString è in ritardo per un metodo di stringa in grado di farlo. Molto bene.
Adam Eberbach

1
Ho trovato (2) sulla licenza di Michael troppo restrittiva per il mio caso d'uso, quindi ho usato la soluzione di Nikita. Includere tre file con licenza Apache-2.0 da Google Toolbox funziona alla grande per me.
jaime

10
L'aggiornamento del codice per ARC sarebbe utile .. Xcode sta lanciando tonnellate di errori ARC e avvisi sulla build
Matej

52

Quello di Daniel è fondamentalmente molto carino e ho risolto alcuni problemi lì:

  1. rimosso il carattere di salto per NSSCanner (altrimenti gli spazi tra due entità continue sarebbero ignorati

    [scanner setCharactersToBeSkipped: nil];

  2. risolto il parsing quando ci sono simboli "&" isolati (non sono sicuro di quale sia l'output "corretto" per questo, l'ho appena confrontato con firefox):

per esempio

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

ecco il codice modificato:

- (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];

    [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;
}

Questa dovrebbe essere la risposta definitiva alla domanda !! Grazie!
boliva

Funzionava benissimo. Sfortunatamente il codice della risposta con il punteggio più alto non funziona più a causa di problemi di ARC, ma funziona.
Ted Kulp

@TedKulp funziona perfettamente, devi solo disabilitare ARC per file. stackoverflow.com/questions/6646052/…
Kyle

Ti farei il pollice in su due volte se potessi.
Kibitz503

Traduzione Swift per le persone ancora in visita a questa domanda in 2016+: stackoverflow.com/a/35303635/1153630
Max Chuquimia

46

A partire da iOS 7, puoi decodificare i caratteri HTML in modo nativo utilizzando un NSAttributedStringcon l' NSHTMLTextDocumentTypeattributo:

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];

La stringa attribuita decodificata verrà ora visualizzata come:  & & <> ™ © ♥ ♣ ♠ ♦.

Nota: funzionerà solo se chiamato nel thread principale.


6
migliore risposta se non è necessario supportare iOS 6 e
versioni

1
no, non è il massimo se qualcuno vuole codificarlo su thread bg; O
badeleux

4
Questo ha funzionato per decodificare un'entità, ma ha anche incasinato un trattino non codificato.
Andrew

Questo è costretto ad accadere sul thread principale. Quindi probabilmente non vuoi farlo se non devi.
Keith Smiley

Si blocca semplicemente la GUI quando si tratta di UITableView. Quindi, non funziona correttamente.
Asif Bilal

35

Nessuno sembra menzionare una delle opzioni più semplici: Google Toolbox per Mac
(nonostante il nome, funziona anche su 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, '&amp;' becomes '&'
///  Handles &#32; and &#x32; cases as well
///
//  Returns:
//    Autoreleased NSString
//
- (NSString *)gtm_stringByUnescapingFromHTML;

E ho dovuto includere solo tre file nel progetto: intestazione, implementazione e GTMDefines.h.


Ho incluso questi tre script, ma come posso usarli ora?
Borut Tomazin

@ borut-t [myString gtm_stringByUnescapingFromHTML]
Nikita Rybak

2
Ho scelto di includere solo quei tre file, quindi ho dovuto farlo per renderlo compatibile con arc: code.google.com/p/google-toolbox-for-mac/wiki/ARC_Compatibility
jaime

devo dire che questa è di gran lunga la soluzione più semplice e leggera
lensovet

Vorrei riuscire a farlo funzionare completamente. Sembra saltarne molti nelle mie corde.
Joseph Toronto

17

Dovrei postarlo su GitHub o qualcosa del genere. Questo rientra in una categoria di NSString, utilizza NSScannerper l'implementazione e gestisce entità di caratteri numerici sia esadecimali che decimali, nonché le solite entità simboliche.

Inoltre, gestisce le stringhe non corrette (quando hai un & seguito da una sequenza di caratteri non valida) in modo relativamente grazioso, il che si è rivelato cruciale nella mia app rilasciata che utilizza questo codice.

- (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;
}

Pezzo di codice molto utile, tuttavia ha un paio di problemi che sono stati risolti da Walty. Grazie per la condivisione!
Michael Waterfall

conosci un modo per mostrare i simboli lambda, mu, nu, pi decodificando le loro entità XML come & micro; ... ect ????
chinthakad

Dovresti evitare di usare gotos come terribile stile di codice. Dovresti sostituire la linea goto finish;con break;.
Storditore

4

Questo è il modo in cui lo faccio usando il framework 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;  

}

Spero che questo possa aiutare qualcuno.


4

puoi usare solo questa funzione per risolvere questo problema.

+ (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;
}

2

Ecco una versione rapida della risposta di Walty Yeung :

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
    }
}

1

In realtà il fantastico framework MWFeedParser di Michael Waterfall (riferito alla sua risposta) è stato biforcato da rmchaara che lo ha aggiornato con il supporto ARC!

Puoi trovarlo su GitHub qui

Funziona davvero alla grande, ho usato il metodo stringByDecodingHTMLEntities e funziona perfettamente.


Ciò risolve i problemi di ARC, ma introduce alcuni avvisi. Penso che sia sicuro ignorarli?
Robert J. Clegg

0

Come se avessi bisogno di un'altra soluzione! Questo è piuttosto semplice e abbastanza efficace:

@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

0

Se hai il riferimento all'entità carattere come stringa, ad esempio @"2318", puoi estrarre una NSString ricodificata con il carattere Unicode corretto utilizzando strtoul;

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

0

Versione Swift 3 della risposta di Jugale

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
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.