Ich frage mich, ob es in Ziel C eine einfache Möglichkeit gibt, ein einfaches HTML-Escape / Unescape durchzuführen. Was ich möchte, ist so etwas wie dieser Pseudocode:
NSString *string = @"<span>Foo</span>";
[string stringByUnescapingHTML];
Welches kehrt zurück
<span>Foo</span>
Hoffentlich werden auch alle anderen HTML-Entitäten und sogar ASCII-Codes wie Ӓ und dergleichen entkoppelt.
Gibt es in Cocoa Touch / UIKit Methoden, um dies zu tun?
iphone
html
objective-c
cocoa-touch
escaping
Alex Wayne
quelle
quelle
Antworten:
Dieser Link enthält die folgende Lösung. Cocoa CF verfügt über die Funktion CFXMLCreateStringByUnescapingEntities, die auf dem iPhone jedoch nicht verfügbar ist.
@interface MREntitiesConverter : NSObject <NSXMLParserDelegate>{ NSMutableString* resultString; } @property (nonatomic, retain) NSMutableString* resultString; - (NSString*)convertEntitiesInString:(NSString*)s; @end @implementation MREntitiesConverter @synthesize resultString; - (id)init { if([super init]) { resultString = [[NSMutableString alloc] init]; } return self; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)s { [self.resultString appendString:s]; } - (NSString*)convertEntitiesInString:(NSString*)s { if (!s) { NSLog(@"ERROR : Parameter string is nil"); } NSString* xmlStr = [NSString stringWithFormat:@"<d>%@</d>", s]; NSData *data = [xmlStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSXMLParser* xmlParse = [[[NSXMLParser alloc] initWithData:data] autorelease]; [xmlParse setDelegate:self]; [xmlParse parse]; return [NSString stringWithFormat:@"%@",resultString]; } - (void)dealloc { [resultString release]; [super dealloc]; } @end
quelle
CFXMLCreateStringByUnescapingEntities
es unter iOS nicht verfügbar ist, können Sie die Definition aus CFXMLParser.c (aus dem Core Foundation-Quellcode) kopieren und in Ihrem Projekt verwenden. Ich habe es getestet und es funktioniert.Überprüfen Sie meine NSString-Kategorie für XMLEntities . Es gibt Methoden zum Dekodieren von XML-Entitäten (einschließlich aller HTML-Zeichenreferenzen), zum Codieren von XML-Entitäten, zum Entfernen von Tags und zum Entfernen von Zeilenumbrüchen und Leerzeichen aus einer Zeichenfolge:
- (NSString *)stringByStrippingTags; - (NSString *)stringByDecodingXMLEntities; // Including all HTML character references - (NSString *)stringByEncodingXMLEntities; - (NSString *)stringWithNewLinesAsBRs; - (NSString *)stringByRemovingNewLinesAndWhitespace;
quelle
pod "GTMNSStringHTMLAdditions"
. Siehe Travis 'Antwort vom September 2015.Eine weitere HTML-NSString-Kategorie von Google Toolbox für Mac
Trotz des Namens funktioniert dies auch unter iOS.
http://google-toolbox-for-mac.googlecode.com/svn/trunk/Foundation/GTMNSString+HTML.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;
Und ich musste nur drei Dateien in das Projekt aufnehmen: Header, Implementierung und
GTMDefines.h
.quelle
'&'
wird'&'
, die auch in abgedeckt ist- (NSString *)gtm_stringByEscapingForHTML;
, später in der Datei definiert.GTMDefines.h
-fno-objc-arc
Compiler-Flags verhindert nicht, dass die Struktur als Fehler in Xcode markiert wird.Dies ist eine unglaublich gehackte Lösung, die ich gemacht habe, aber wenn Sie einfach einer Zeichenfolge entkommen möchten, ohne sich Gedanken über das Parsen machen zu müssen, gehen Sie folgendermaßen vor:
-(NSString *)htmlEntityDecode:(NSString *)string { string = [string stringByReplacingOccurrencesOfString:@""" withString:@"\""]; string = [string stringByReplacingOccurrencesOfString:@"'" withString:@"'"]; string = [string stringByReplacingOccurrencesOfString:@"<" withString:@"<"]; string = [string stringByReplacingOccurrencesOfString:@">" withString:@">"]; string = [string stringByReplacingOccurrencesOfString:@"&" withString:@"&"]; // Do this last so that, e.g. @"&lt;" goes to @"<" not @"<" return string; }
Ich weiß, dass es keineswegs elegant ist, aber es erledigt den Job. Sie können dann ein Element dekodieren, indem Sie Folgendes aufrufen:
string = [self htmlEntityDecode:string];
Wie ich schon sagte, es ist hacky, aber es funktioniert. Wenn Sie eine Zeichenfolge codieren möchten, kehren Sie einfach die Parameter stringByReplacingOccurencesOfString um.
quelle
In iOS 7 können Sie die Fähigkeit von NSAttributedString verwenden, HTML zu importieren, um HTML-Entitäten in einen NSString zu konvertieren.
Z.B:
@interface NSAttributedString (HTML) + (instancetype)attributedStringWithHTMLString:(NSString *)htmlString; @end @implementation NSAttributedString (HTML) + (instancetype)attributedStringWithHTMLString:(NSString *)htmlString { NSDictionary *options = @{ NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute :@(NSUTF8StringEncoding) }; NSData *data = [htmlString dataUsingEncoding:NSUTF8StringEncoding]; return [[NSAttributedString alloc] initWithData:data options:options documentAttributes:nil error:nil]; } @end
Dann in Ihrem Code, wenn Sie die Entitäten bereinigen möchten:
NSString *cleanString = [[NSAttributedString attributedStringWithHTMLString:question.title] string];
Dies ist wahrscheinlich der einfachste Weg, aber ich weiß nicht, wie performant es ist. Sie sollten wahrscheinlich ziemlich sicher sein, dass der Inhalt Ihrer "Reinigung" keine
<img>
Tags oder ähnliches enthält, da diese Methode diese Bilder während der Konvertierung von HTML in NSAttributedString herunterlädt. :) :)quelle
this is test
von<b>this</b> is <a href='test'>test</a>
.Hier ist eine Lösung, die alle Zeichen neutralisiert (indem sie alle HTML-codierten Entitäten für ihren Unicode-Wert festgelegt werden) ... Verwendet diese für meine Anforderungen (um sicherzustellen, dass eine Zeichenfolge, die vom Benutzer stammt, aber in einer Webansicht platziert wurde, keine haben kann XSS-Angriffe):
Schnittstelle:
@interface NSString (escape) - (NSString*)stringByEncodingHTMLEntities; @end
Implementierung:
@implementation NSString (escape) - (NSString*)stringByEncodingHTMLEntities { // Rather then mapping each individual entity and checking if it needs to be replaced, we simply replace every character with the hex entity NSMutableString *resultString = [NSMutableString string]; for(int pos = 0; pos<[self length]; pos++) [resultString appendFormat:@"&#x%x;",[self characterAtIndex:pos]]; return [NSString stringWithString:resultString]; } @end
Anwendungsbeispiel:
UIWebView *webView = [[UIWebView alloc] init]; NSString *userInput = @"<script>alert('This is an XSS ATTACK!');</script>"; NSString *safeInput = [userInput stringByEncodingHTMLEntities]; [webView loadHTMLString:safeInput baseURL:nil];
Ihr Kilometerstand wird variieren.
quelle
@"&#x%04x;"
, ich würde einen einfachen alphanumerischen Detektor hinzufügen und einfach kopieren solche Charaktere ohne zu entkommen.Die am wenigsten invasive und leichteste Methode zum Codieren und Decodieren von HTML- oder XML-Zeichenfolgen ist die Verwendung des GTMNSStringHTMLAdditions CocoaPod .
Es ist einfach die Kategorie Google Toolbox für Mac NSString
GTMNSString+HTML
, von der die Abhängigkeit befreit istGTMDefines.h
. Alles, was Sie hinzufügen müssen, ist ein .h und ein .m, und Sie können loslegen.Beispiel:
#import "GTMNSString+HTML.h" // Encoding a string with XML / HTML elements NSString *stringToEncode = @"<TheBeat>Goes On</TheBeat>"; NSString *encodedString = [stringToEncode gtm_stringByEscapingForHTML]; // encodedString looks like this now: // <TheBeat>Goes On</TheBeat> // Decoding a string with XML / HTML encoded elements NSString *stringToDecode = @"<TheBeat>Goes On</TheBeat>"; NSString *decodedString = [stringToDecode gtm_stringByUnescapingFromHTML]; // decodedString looks like this now: // <TheBeat>Goes On</TheBeat>
quelle
Dies ist eine einfach zu verwendende Implementierung der NSString-Kategorie:
Es ist noch lange nicht vollständig, aber Sie können hier einige fehlende Entitäten hinzufügen: http://code.google.com/p/statz/source/browse/trunk/NSString%2BHTML.m
Verwendung:
#import "NSString+HTML.h" NSString *raw = [NSString stringWithFormat:@"<div></div>"]; NSString *escaped = [raw htmlEscapedString];
quelle
Der obige MREntitiesConverter ist ein HTML-Stripper, kein Encoder.
Wenn Sie einen Encoder benötigen, klicken Sie hier: Codieren Sie NSString für XML / HTML
quelle
MREntitiesConverter funktioniert nicht, um fehlerhaften XML-Dateien zu entkommen. Bei einer einfachen URL schlägt dies fehl:
http://www.google.com/search?client=safari&rls=de&q=fail&ie=UTF-8&oe=UTF-8
quelle
Wenn Sie ein Literal generieren müssen, können Sie ein Tool wie das folgende verwenden:
http://www.freeformatter.com/java-dotnet-escape.html#ad-output
um die Arbeit für Sie zu erledigen.
Siehe auch diese Antwort .
quelle
Diese einfachste Lösung besteht darin, eine Kategorie wie folgt zu erstellen:
Hier ist die Header-Datei der Kategorie:
#import <Foundation/Foundation.h> @interface NSString (URLEncoding) -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding; @end
Und hier ist die Implementierung:
#import "NSString+URLEncoding.h" @implementation NSString (URLEncoding) -(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding { return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)self, NULL, (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ", CFStringConvertNSStringEncodingToEncoding(encoding)); } @end
Und jetzt können wir das einfach machen:
NSString *raw = @"hell & brimstone + earthly/delight"; NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@", [raw urlEncodeUsingEncoding:NSUTF8Encoding]]; NSLog(url);
Die Credits für diese Antwort gehen auf die folgende Website: -
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
quelle
Warum nicht einfach benutzen?
NSData *data = [s dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; NSString *result = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; return result;
Noob Frage, aber in meinem Fall funktioniert es ...
quelle
Es gibt noch eine andere Lösung, die erwähnt werden muss. Erstellen Sie einfach eine
UIWebView
, laden Sie die codierte Zeichenfolge und erhalten Sie den Text zurück. Es entgeht den Tags "<>" und dekodiert auch alle HTML-Entitäten (z. B. "& gt;") und funktioniert möglicherweise dort, wo andere dies nicht tun (z. B. unter Verwendung von Kyrillik). Ich denke nicht, dass es die beste Lösung ist, aber es kann nützlich sein, wenn die oben genannten Lösungen nicht funktionieren.Hier ist ein kleines Beispiel mit ARC:
@interface YourClass() <UIWebViewDelegate> @property UIWebView *webView; @end @implementation YourClass - (void)someMethodWhereYouGetTheHtmlString:(NSString *)htmlString { self.webView = [[UIWebView alloc] init]; NSString *htmlString = [NSString stringWithFormat:@"<html><body>%@</body></html>", self.description]; [self.webView loadHTMLString:htmlString baseURL:nil]; self.webView.delegate = self; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { self.webView = nil; } - (void)webViewDidFinishLoad:(UIWebView *)webView { self.webView = nil; NSString *escapedString = [self.webView stringByEvaluatingJavaScriptFromString:@"document.body.textContent;"]; } - (void)webViewDidStartLoad:(UIWebView *)webView { // Do Nothing } @end
quelle