views:

5115

answers:

6

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

Thanks!

+4  A: 

There isn't an NSString method that does that. You'll have to write your own function that does string replacements. It is sufficient to do the following replacements:

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

Something like this should do (haven't tried):

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

thesamet
I was hoping to avoid this, but thanks for the info about them not having something built in.
Billy
This solution doesn't work in all cases. I recently ran into a bug with the UTF-8 string that included the character 0xE28099 which translates to UTF-8 2019 or the 'right single quotation mark'. Such extended characters are not handled in the above example, and caused errors in our client's server (as they were out of spec). The above example work work in most cases, but not all.
Aftermathew
Although it does occur to me now that our client's XML Schema specifically called out ISO-8859-1, and I'm not sure if this would be a problem otherwise.
Aftermathew
Just a quick note, if you're going perform a lot of these escapes on a lot of XML/HTML inside 1 run loop then don't forget to wrap each encode in an `NSAutoreleasePool`!
Michael Waterfall
+3  A: 

For URL encoding:

NSString * encodedString = [originalString
      stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

See Apple's NSString documentation for more info.

For HTML encoding:

Check out CFXMLCreateStringByEscapingEntities, which is part of the Core Foundation XML library, but should still do the trick.

e.James
I believe that's URL encoding, not HTML encoding.
JW
@JW: Yes, you are absolutely right. I didn't know there was a difference!
e.James
stringByAddingPercentEscapesUsingEncoding is what I am currently using, unfortunately it doesn't work for some of the more odd characters.
Billy
+11  A: 

I use Google Toolbox for Mac (works on iPhone). In particular, see the additions to NSString in GTMNSString+HTML.h and GTMNSString+XML.h.

Chris Lundie
That looks useful, thanks!
Billy
A: 

CFXMLCreateStringByEscapingEntities is not available on iPhone.

Mike
+3  A: 

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:@"&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;
}
Mike
+2  A: 

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:@"&#x39;" 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];
}
Tod Cunningham
Thanks todd, very useful
the_snitch