2013-04-03 11 views
9

Sto provando a convertire un semplice codice HTML in un valore stringa in un oggetto JSON e sto riscontrando problemi nel far sì che la codifica stringa non esca dalla stringa in NSJSONSerialization .NSJSONSerializzazione serializzazione di una stringa contenente barre rovesce/e HTML viene sfuggito in modo errato

Esempio ... Ho una stringa che contiene un testo di base HTML:

NSString *str = @"<html><body><p>Samples/Text</p></body></html>"; 

Il risultato desiderato è JSON con HTML come valore:

{ 
    "Title":"My Title", 
    "Instructions":"<html><body><p>Samples/Text</p></body></html>" 
} 

sto usando lo standard tecnica per convertire un NSDictionary ad un NSString contenente JSON:

NSMutableDictionary *dict = [NSMutableDictionary dictionary]; 
[dict setObject:str forKey:@"Instructions"]; 
[dict setObject:@"My Title" forKey:@"Title"]; 

NSError *err; 
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&err]; 
NSString *resultingString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSLog(@"%@", resultingString); 

Il JSON prodotta con questo metodo è v Alid, tuttavia il codice HTML ha tutte le barre sono fuggiti:

{ 
    "Title":"My Title", 
    "Instructions":"<html><body><p>Samples \/ Text<\/p><\/body><\/html>" 
} 

Questo crea HTML non valido nel istruzioni JSON stringa.

Mi piacerebbe restare con NSJSONSerialization poiché lo utilizziamo in qualsiasi altro posto nel nostro framework e sono stato masterizzato prima di passare alle librerie non Apple quando vengono interrotte. Ho provato molte diverse stringhe di stringhe e tutte sfuggono alle parentesi angolari.

Apparentemente \/è una rappresentazione valida in JavaScript per i caratteri /, che è il motivo per cui la barra diretta è sfuggita (anche l'editor di testo StackOverflow lo ha sfuggito). Vedi: escaping json string with a forward slash? e anche JSON: why are forward slashes escaped?. Solo che non voglio farlo e non sembra essere un modo per impedire a iOS di sfuggire alle barre in avanti nei valori di stringa durante la serializzazione.

+0

Un altro buon motivo per non utilizzare NSJSONSerialization, suppongo. Si possono sempre scansionare i dati e sostituire i "\ /" caratteri adiacenti con "/", ma un po 'disordinati. –

+0

Questo è quello che sto facendo per ora, che sembra un hack.Sfortunatamente ogni framework iOS di terze parti che ho usato finora è stato disattivato dopo che gli autori originali si sono annoiati o occupati. – JasonD

+1

Usiamo ancora SBJSON. E nel peggiore dei casi puoi scrivere il tuo - in realtà si tratta solo di linee di codice da 2K, a patto di non essere troppo stravagante. –

risposta

3

Credo che NSJSONSerialization si comporti come progettato per quanto riguarda la codifica HTML.

Se si guardano alcune domande (1, 2) sulla codifica HTML in JSON vedrete che le risposte menzionano sempre l'escape delle barre in avanti.

JSON non richiede avanti slash per essere sfuggito, ma HTML non permette una stringa javascript di contenere </ in quanto può essere confuso con la fine del tag <SCRIPT>.

vedere le risposte here, here e più diretta sul w3.org HTML4 Appendix cui si afferma in B.3.2 Specifying non-HTML data

ILLEGAL EXAMPLE: 
The following script data incorrectly contains a "</" sequence (as part of "</EM>") before the SCRIPT end tag: 

<SCRIPT type="text/javascript"> 
    document.write ("<EM>This won't work</EM>") 
</SCRIPT> 

Anche se questo comportamento può causare problemi per voi NSJSONSerialisation sta solo giocando per l'età vecchie regole di codifica dei dati HTML per l'uso in <SCRIPT> tag.

1

Ecco la sottoclasse di AFJSONRequestSerializer per rimuovere \ prima dei simboli / nel JSON risultante; utile se si utilizza AFNetworking

class SanitizedAFJSONRequestSerializer: AFJSONRequestSerializer 
{ 
    override func requestBySerializingRequest(request: NSURLRequest!, withParameters parameters: AnyObject!, error: NSErrorPointer) -> NSURLRequest! 
    { 
     var request = super.requestBySerializingRequest(request, withParameters: parameters, error: error) 

     if let jsonData = request.HTTPBody 
     { 
      if let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding) as? String 
      { 
       let sanitizedString = jsonString.stringByReplacingOccurrencesOfString("\\/", withString: "/", options: NSStringCompareOptions.CaseInsensitiveSearch, range:nil) as NSString 

       println("sanitized json string: \(sanitizedString)") 

       var mutableRequest = request.mutableCopy() as! NSMutableURLRequest 
       mutableRequest.HTTPBody = sanitizedString.dataUsingEncoding(NSUTF8StringEncoding) 
       request = mutableRequest 
      } 
     } 

     return request 
    } 
} 
Problemi correlati