Encode NSString for XML/HTML

2020-01-25 04:37发布

Is there a way to HTML encode a string (NSString) in Objective-C, something along the lines of Server.HtmlEncode in .NET?

15条回答
ゆ 、 Hurt°
2楼-- · 2020-01-25 05:10

the samets's routine forgot the hex digit. Here's the routine I came up with that works:

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

NSString    *returnStr = nil;

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

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

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"'" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"9" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"’" withString:@"'"  ];

        returnStr = [ returnStr stringByReplacingOccurrencesOfString:@"–" withString:@"'"  ];

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

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

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

    return returnStr;
}
查看更多
干净又极端
3楼-- · 2020-01-25 05:10

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);
查看更多
ら.Afraid
4楼-- · 2020-01-25 05:12

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
查看更多
我只想做你的唯一
5楼-- · 2020-01-25 05:14

I took Mike's work and turn it into a category for NSMutableString and NSString

Make a Category for NSMutableString with:

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

Make a Category for NSString with:

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

    return [unescapeStr xmlSimpleUnescape];
}


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

    return [escapeStr xmlSimpleEscape];
}

* A Swift 2.0 Version *

The Objective-C version is a little more efficient as it does mutable operations on the string. However, this is a swift way to do simple escaping:

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

I could have used the NSString bridging capabilities to write something very similar to the NSString version, but I decided to do it more swifty.

查看更多
迷人小祖宗
6楼-- · 2020-01-25 05:15

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

查看更多
Anthone
7楼-- · 2020-01-25 05:16

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!
}
查看更多
登录 后发表回答