Есть ли способ HTML кодировать строку (NSString) в objective-c, что-то вроде строк Server.HtmlEncode в .NET?
Спасибо!
Есть ли способ HTML кодировать строку (NSString) в objective-c, что-то вроде строк Server.HtmlEncode в .NET?
Спасибо!
Не существует метода NSString, который делает это. Вам придется написать свою собственную функцию, которая заменяет строки. Достаточно выполнить следующие замены:
Что-то вроде этого должно (не пробовал):
[[[[[myStr stringByReplacingOccurrencesOfString: @"&" withString: @"&"]
stringByReplacingOccurrencesOfString: @"\"" withString: @"""]
stringByReplacingOccurrencesOfString: @"'" withString: @"'"]
stringByReplacingOccurrencesOfString: @">" withString: @">"]
stringByReplacingOccurrencesOfString: @"<" withString: @"<"];
Я взял работу Майка и превратил ее в категорию для NSMutableString и NSString
Создайте категорию для NSMutableString с помощью
- (NSMutableString *)xmlSimpleUnescape
{
[self replaceOccurrencesOfString:@"&" withString:@"&" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@""" withString:@"\"" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"'" withString:@"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"'" withString:@"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"’" withString:@"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"–" withString:@"-" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@">" withString:@">" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"<" withString:@"<" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
return self;
}
- (NSMutableString *)xmlSimpleEscape
{
[self replaceOccurrencesOfString:@"&" withString:@"&" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"\"" withString:@""" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"'" withString:@"'" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@">" withString:@">" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
[self replaceOccurrencesOfString:@"<" withString:@"<" options:NSLiteralSearch range:NSMakeRange(0, [self length])];
return self;
}
Создайте категорию для NSString с помощью
- (NSString *)xmlSimpleUnescapeString
{
NSMutableString *unescapeStr = [NSMutableString stringWithString:self];
return [unescapeStr xmlSimpleUnescape];
}
- (NSString *)xmlSimpleEscapeString
{
NSMutableString *escapeStr = [NSMutableString stringWithString:self];
return [escapeStr xmlSimpleEscape];
}
* Версия Swift 2.0 *
Версия Objective-C немного более эффективна, так как она выполняет изменяемые операции над строкой. Однако это быстрый способ сделать простое экранирование:
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 = [
("&", "&"),
(""", "\""),
("'", "'"),
("'", "'"),
("’", "'"),
("–", "-"),
(">", ">"),
("<", "<")]
return self.simpleReplace(mapList)
}
func xmlSimpleEscape() -> String
{
let mapList : SimpleToFromRepalceList = [
("&", "&"),
("\"", """),
("'", "'"),
(">", ">"),
("<", "<")]
return self.simpleReplace(mapList)
}
}
Я мог бы использовать возможности моста NSString для написания чего-то очень похожего на версию NSString, но я решил сделать это более осторожным.
Я использую Google Toolbox для Mac (работает на iPhone). В частности, см. Дополнения к NSString в GTMNSString + HTML.h и GTMNSString + XML.h.
Для кодировки URL:
NSString * encodedString = [originalString
stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
Подробнее см. Документацию Apple NSString.
Для кодирования HTML:
Откажитесь от CFXMLCreateStringByEscapingEntities, который является частью XML-библиотеки Core Foundation, но все равно должен сделать трюк.
программа samets забыла шестнадцатеричную цифру. В этой рутине я придумал, что работает:
- (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:@"<" withString:@"<" ];
returnStr = [ [ NSString alloc ] initWithString:returnStr ];
}
return returnStr;
}
Вот более эффективная реализация этой управляющей логики xml.
+ (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 = @""";
}
else if (c == '\'')
{
replaceWithStr = @"'";
}
else if (c == '<')
{
replaceWithStr = @"<";
}
else if (c == '>')
{
replaceWithStr = @">";
}
else if (c == '&')
{
replaceWithStr = @"&";
}
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];
}
}
Если вы можете использовать NSXMLNode (в OS X) Вот трюк:
NSString *string = @"test<me>"
NSXMLNode *textNode = [NSXMLNode textWithStringValue:string];
NSString *escapedString = [textNode.XMLString];
Я собрал проект быстрого примера, в котором Майк и Тод ответят здесь.
Делает простое кодирование /unencoding мертвым:
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);
У меня есть довольно мощный кодер URL с открытым исходным кодом, который вы можете найти здесь.
Что отличает его от подхода NSString stringByAddingPercentEscapesUsingEncoding, так это то, что он уважает доменную часть URL-адреса и только кодирует часть пути.
Я тестировал его с более чем 10 000 URL-адресов, и он очень хорошо работает.
Удачи и дайте мне знать, если у вас есть проблемы с ним!
Вот моя быстрая категория для кодирования/декодирования html:
extension String
{
static let htmlEscapedDictionary = [
"&": "&",
""" : "\"",
"'" : "'",
"9" : "'",
"’" : "'",
"–" : "'",
">" : ">",
"<" : "<"]
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
}
}
Я думаю, что обратная сторона htmlEscapedDictionary могла бы использоваться также в unescapedHtmlString
Примечание.. Как отметил MarkBau в комментарии ниже: Поскольку Swift не гарантирует порядок словарей, сначала замените &
.
Я не уверен, будет ли он работать во всех случаях, но может быть проще окружить ваш текст CDATA:
<xmltag><![CDATA[some <b>long</b> <i>xml</i> text]]></xmltag>
что такое CDATA: Что делает <! [CDATA []] > в XML означает?
Это самое простое решение - создать категорию, как показано ниже:
Вот заголовок файла категорий:
#import <Foundation/Foundation.h>
@interface NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
@end
И реализует реализацию:
#import "NSString+URLEncoding.h"
@implementation NSString (URLEncoding)
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {
return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding));
}
@end
И теперь мы можем просто сделать это:
NSString *raw = @"hell & brimstone + earthly/delight";
NSString *url = [NSString stringWithFormat:@"http://example.com/example?param=%@",
[raw urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(url);
Кредиты для этого ответа поступают на веб-сайт ниже: -
http://madebymany.com/blog/url-encoding-an-nsstring-on-ios
См. ниже ответ:
NSString *content = global.strPrivacyPolicy;
content = [[[[[content stringByReplacingOccurrencesOfString: @"&" withString: @"&"]
stringByReplacingOccurrencesOfString:@""" withString:@"\" "]
stringByReplacingOccurrencesOfString: @"'" withString:@"'"]
stringByReplacingOccurrencesOfString: @">" withString: @">"]
stringByReplacingOccurrencesOfString: @"<" withString:@"<"];
[_webViewPrivacy loadHTMLString:content baseURL:nil];
Используйте сообщение в следующем примере:
anyStringConverted = [anyString stringByReplacingOccurrencesOfString:@"\n" withString:@"<br>"];
Это преобразует команду "новая строка" в соответствующий html-код. Но для преобразования символов вам нужно написать соответствующее число html. Вы можете увидеть полный список html-номеров здесь,