Frage

Gibt es eine Möglichkeit, eine String (NSString) in Objective-C zu codieren, etwas in der Reihe von Server.htmlencode in .NET?

War es hilfreich?

Lösung

Es gibt keine NSString -Methode, die das tut. Sie müssen Ihre eigene Funktion schreiben, die Zeichenfolge ersetzt. Es reicht aus, die folgenden Ersetzungen durchzuführen:

  • '&' => "&"
  • '"' =>" ""
  • '\'' => "'"
  • '>' => ">"
  • '<' => "<"

So etwas sollte (nicht versucht):

[[[[[myStr stringByReplacingOccurrencesOfString: @"&" withString: @"&amp;"]
 stringByReplacingOccurrencesOfString: @"\"" withString: @"&quot;"]
 stringByReplacingOccurrencesOfString: @"'" withString: @"&#39;"]
 stringByReplacingOccurrencesOfString: @">" withString: @"&gt;"]
 stringByReplacingOccurrencesOfString: @"<" withString: @"&lt;"];

Andere Tipps

Ich nahm Mikes Arbeit und verwandelte sie in eine Kategorie für NSMutablestring und NSString

Machen Sie eine Kategorie für NSMutablestring mit:

- (NSMutableString *)xmlSimpleUnescape
{
    [self replaceOccurrencesOfString:@"&amp;"  withString:@"&"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&quot;" withString:@"\"" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&#x27;" withString:@"'"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&#39;"  withString:@"'"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&#x92;" withString:@"'"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&#x96;" withString:@"-"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&gt;"   withString:@">"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"&lt;"   withString:@"<"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];

    return self;
}

- (NSMutableString *)xmlSimpleEscape
{
    [self replaceOccurrencesOfString:@"&"  withString:@"&amp;"  options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"\"" withString:@"&quot;" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"'"  withString:@"&#x27;" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@">"  withString:@"&gt;"   options:NSLiteralSearch range:NSMakeRange(0, [self length])];
    [self replaceOccurrencesOfString:@"<"  withString:@"&lt;"   options:NSLiteralSearch range:NSMakeRange(0, [self length])];

    return self;
}

Machen Sie eine Kategorie für NSString mit:

- (NSString *)xmlSimpleUnescapeString
{
    NSMutableString *unescapeStr = [NSMutableString stringWithString:self];

    return [unescapeStr xmlSimpleUnescape];
}


- (NSString *)xmlSimpleEscapeString
{
    NSMutableString *escapeStr = [NSMutableString stringWithString:self];

    return [escapeStr xmlSimpleEscape];
}

* Eine Swift 2.0 -Version *

Die Ziel-C-Version ist etwas effizienter wie veränderliche Vorgänge in der Zeichenfolge. Dies ist jedoch eine schnelle Möglichkeit, einfach zu entkommen:

extension String
{
    typealias SimpleToFromRepalceList = [(fromSubString:String,toSubString:String)]

    // See http://stackoverflow.com/questions/24200888/any-way-to-replace-characters-on-swift-string
    //
    func simpleReplace( mapList:SimpleToFromRepalceList ) -> String
    {
        var string = self

        for (fromStr, toStr) in mapList {
            let separatedList = string.componentsSeparatedByString(fromStr)
            if separatedList.count > 1 {
                string = separatedList.joinWithSeparator(toStr)
            }
        }

        return string
    }

    func xmlSimpleUnescape() -> String
    {
        let mapList : SimpleToFromRepalceList = [
            ("&amp;",  "&"),
            ("&quot;", "\""),
            ("&#x27;", "'"),
            ("&#39;",  "'"),
            ("&#x92;", "'"),
            ("&#x96;", "-"),
            ("&gt;",   ">"),
            ("&lt;",   "<")]

        return self.simpleReplace(mapList)
    }

    func xmlSimpleEscape() -> String
    {
        let mapList : SimpleToFromRepalceList = [
            ("&",  "&amp;"),
            ("\"", "&quot;"),
            ("'",  "&#x27;"),
            (">",  "&gt;"),
            ("<",  "&lt;")]

        return self.simpleReplace(mapList)
    }
}

Ich hätte die NSSTRING -Überbrückungsfunktionen verwenden können, um etwas sehr Ähnliches wie die NSString -Version zu schreiben, aber ich habe mich entschlossen, es zu tun.

ich benutze Google Toolbox für Mac (funktioniert auf dem iPhone). Insbesondere sehen Sie die Ergänzungen zu NSString in Gtmnsstring+html.h und Gtmnsstring+xml.h.

Für URL -Codierung:

NSString * encodedString = [originalString
      stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

Sehen Apples NSString -Dokumentation Für mehr Information.

Für HTML -Codierung:

Kasse CFXMLCreateStringByScapingentities, was Teil der Core Foundation XML -Bibliothek ist, sollte aber trotzdem den Trick machen.

Die Routine der Samets vergaß die Sechskantendigheit. Hier ist die Routine, die ich mir ausgedacht habe:

- (NSString*)convertEntities:(NSString*)string
{

NSString    *returnStr = nil;

    if( string )
    {
        returnStr = [ string stringByReplacingOccurrencesOfString:@"&amp;" withString: @"&"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&#x27;" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&#x39;" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&#x92;" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&#x96;" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"  ];

        returnStr = [ [ NSString alloc ] initWithString:returnStr ];
    }

    return returnStr;
}

Hier finden Sie eine effizientere Implementierung dieser XML -Escape -Logik.

+ (NSString*) xmlSimpleEscape:(NSString*)unescapedStr
{
  if (unescapedStr == nil || [unescapedStr length] == 0) {
    return unescapedStr;
  }

  const int len = [unescapedStr length];
  int longer = ((int) (len * 0.10));
  if (longer < 5) {
    longer = 5;
  }
  longer = len + longer;
  NSMutableString *mStr = [NSMutableString stringWithCapacity:longer];

  NSRange subrange;
  subrange.location = 0;
  subrange.length = 0;

  for (int i = 0; i < len; i++) {
    char c = [unescapedStr characterAtIndex:i];
    NSString *replaceWithStr = nil;

    if (c == '\"')
    {
      replaceWithStr = @"&quot;";
    }
    else if (c == '\'')
    {
      replaceWithStr = @"&#x27;";
    }
    else if (c == '<')
    {
      replaceWithStr = @"&lt;";
    }
    else if (c == '>')
    {
      replaceWithStr = @"&gt;";
    }
    else if (c == '&')
    {
      replaceWithStr = @"&amp;";
    }

    if (replaceWithStr == nil) {
      // The current character is not an XML escape character, increase subrange length

      subrange.length += 1;
    } else {
      // The current character will be replaced, but append any pending substring first

      if (subrange.length > 0) {
        NSString *substring = [unescapedStr substringWithRange:subrange];
        [mStr appendString:substring];
      }

      [mStr appendString:replaceWithStr];

      subrange.location = i + 1;
      subrange.length = 0;
    }
  }

  // Got to end of unescapedStr so append any pending substring, in the
  // case of no escape characters this will append the whole string.

  if (subrange.length > 0) {
    if (subrange.location == 0) {
      [mStr appendString:unescapedStr];      
    } else {
      NSString *substring = [unescapedStr substringWithRange:subrange];
      [mStr appendString:substring];
    }
  }

  return [NSString stringWithString:mStr];
}

+ (NSString*) formatSimpleNode:(NSString*)tagname value:(NSString*)value
{
  NSAssert(tagname != nil, @"tagname is nil");
  NSAssert([tagname length] > 0, @"tagname is the empty string");

  if (value == nil || [value length] == 0) {
    // Certain XML parsers don't like empty nodes like "<foo/>", use "<foo />" instead
    return [NSString stringWithFormat:@"<%@ />", tagname];
  } else {
    NSString *escapedValue = [self xmlSimpleEscape:value];
    return [NSString stringWithFormat:@"<%@>%@</%@>", tagname, escapedValue, tagname];    
  }
}

Wenn Sie NSXMLNODE (unter OS X) verwenden können, ist hier der Trick:

NSString *string = @"test<me>"
NSXMLNode *textNode = [NSXMLNode textWithStringValue:string];
NSString *escapedString = [textNode.XMLString];

Hier ist meine Swift -Kategorie für HTML -Codierung/Decodierung:

extension String
{
    static let htmlEscapedDictionary = [
        "&amp;": "&",
        "&quot;" : "\"",
        "&#x27;" : "'",
        "&#x39;" : "'",
        "&#x92;" : "'",
        "&#x96;" : "'",
        "&gt;" : ">",
        "&lt;" : "<"]

    var escapedHtmlString : String {
        var newString = "\(self)"

        for (key, value) in String.htmlEscapedDictionary {
            newString.replace(value, withString: key)
        }
        return newString
    }

    var unescapedHtmlString : String {
        let encodedData = self.dataUsingEncoding(NSUTF8StringEncoding)!
        let attributedOptions : [String: AnyObject] = [
            NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType,
            NSCharacterEncodingDocumentAttribute: NSUTF8StringEncoding
        ]
        let attributedString = NSAttributedString(data: encodedData, options: attributedOptions, documentAttributes: nil, error: nil)!
        return attributedString.string
    }

    mutating func replace(originalString:String, withString newString:String)
    {
        let replacedString = self.stringByReplacingOccurrencesOfString(originalString, withString: newString, options: nil, range: nil)
        self = replacedString
    }
}

Ich glaube

Notiz: Wie Markbau im Kommentar unten betonte: Da Swift die Reihenfolge der Wörterbücher nicht garantiert, stellen Sie sicher, dass Sie ersetzen & Erste.

I am not copletely sure if it will work in all cases, but may be it's easier to surround your text with CDATA:

<xmltag><![CDATA[some <b>long</b> <i>xml</i> text]]></xmltag>

what is CDATA: What does <![CDATA[]]> in XML mean?

I put together a quick example project using Mike and Tod's answers here.

Makes the encoding/unencoding dead simple:

NSString *html = @"<p>This \"paragraph\" contains quoted & 'single' quoted stuff.</p>";
NSLog(@"Original String: %@", html);

NSString *escapedHTML = [html xmlSimpleEscapeString];
NSLog(@"Escaped String: %@", escapedHTML);

NSString *unescapedHTML = [escapedHTML xmlSimpleUnescapeString];
NSLog(@"Unescaped String: %@", unescapedHTML);

Swift 4

extension String {
    var xmlEscaped: String {
        return replacingOccurrences(of: "&", with: "&amp;")
            .replacingOccurrences(of: "\"", with: "&quot;")
            .replacingOccurrences(of: "'", with: "&#39;")
            .replacingOccurrences(of: ">", with: "&gt;")
            .replacingOccurrences(of: "<", with: "&lt;")
    }
}

This easiest solution is to create a category as below:

Here’s the category’s header file:

#import <Foundation/Foundation.h>
@interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
@end

And here’s the implementation:

#import "NSString+URLEncoding.h"
@implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
               (CFStringRef)self,
               NULL,
               (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
               CFStringConvertNSStringEncodingToEncoding(encoding));
}
@end

And now we can simply do this:

NSString *raw = @"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@",
            [raw urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(url);

The credits for this answer goes to the website below:-

http://madebymany.com/blog/url-encoding-an-nsstring-on-ios

Refer below answer:

NSString *content = global.strPrivacyPolicy;
content =  [[[[[content stringByReplacingOccurrencesOfString: @"&amp;" withString: @"&"]
stringByReplacingOccurrencesOfString:@"&quot;"  withString:@"\" "]
stringByReplacingOccurrencesOfString: @"&#39;"  withString:@"'"]
stringByReplacingOccurrencesOfString: @"&gt;" withString: @">"]
stringByReplacingOccurrencesOfString:  @"&lt;" withString:@"<"];
[_webViewPrivacy loadHTMLString:content baseURL:nil];

Use the message in the example below :

anyStringConverted = [anyString stringByReplacingOccurrencesOfString:@"\n" withString:@"<br>"]; 

This converts 'new line' command to corresponding html code. But to convert symbols, you have to write the corresponding html number. You can see the complete list of html numbers here at

http://www.ascii.cl/htmlcodes.htm

I found the only way that uses only built-in functions (not manual parsing) and covers all cases. Requires AppKit/UIKit in addition to Foundation. This is Swift but can easily be Objective-C:

func encodedForHTML() -> String {

    // make a plain attributed string and then use its HTML write functionality
    let attrStr = NSAttributedString(string: self)

    // by default, the document outputs a whole HTML element
    // warning: if default apple implementation changes, this may need to be tweaked
    let options: [NSAttributedString.DocumentAttributeKey: Any] = [
            .documentType: NSAttributedString.DocumentType.html,
            .excludedElements: [
                "html",
                "head",
                "meta",
                "title",
                "style",
                "p",
                "body",
                "font",
                "span"
            ]
    ]

    // generate data and turn into string
    let data = try! attrStr.data(from: NSRange(location: 0, length: attrStr.length), documentAttributes: options)
    let str = String(data: data, encoding: .utf8)!

    // remove <?xml line
    return str.components(separatedBy: .newlines).dropFirst().first!
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top