Кодировать NSString для XML / HTML

Есть ли способ HTML кодировать строку (NSString) в объекте-c, что-то вроде строк Server.HtmlEncode в .NET?

Благодаря!

Это не метод NSString. Вам придется написать свою собственную функцию, которая заменяет строки. Достаточно выполнить следующие замены:

  • ‘&’ => “& amp;”
  • ‘”‘ =>” & quot; ”
  • ‘\’ ‘=> “& # 39;”
  • ‘>’ => “& gt;”
  • ‘<' => “& lt;”

Что-то вроде этого должно (не пробовал):

[[[[[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, но все равно должен делать трюк.

в рутине саметов забыли шестнадцатеричную цифру. Вот рутина, которую я придумал:

 - (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 "", use "" instead return [NSString stringWithFormat:@"<%@ />", tagname]; } else { NSString *escapedValue = [self xmlSimpleEscape:value]; return [NSString stringWithFormat:@"<%@>%@", tagname, escapedValue, tagname]; } } 

Если вы можете использовать NSXMLNode (на OS X) Вот трюк:

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

Вот моя быстрая категория для кодирования / декодирования 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:

 long xml text]]> 

что такое CDATA: что означает в XML?

Я собрал быстрый пример проекта, используя ответы Майка и Тода.

Делает кодирование / unencoding мертвым просто:

 NSString *html = @"

This \"paragraph\" contains quoted & 'single' quoted stuff.

"; 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-адресов, и он очень хорошо работает.

Удачи и дайте мне знать, если у вас есть проблемы с этим!

Это самое простое решение – создать категорию, как показано ниже:

Вот заголовок файла категории:

 #import  @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:@"
"];

Это преобразует команду «новая строка» в соответствующий html-код. Но для преобразования символов вам нужно написать соответствующее число html. Вы можете увидеть полный список html-номеров здесь

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

Я нашел единственный способ, который использует только встроенные функции (а не ручную parsingку) и охватывает все случаи. Требуется AppKit / UIKit в дополнение к Foundation. Это Swift, но может быть легко 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  
  • Список синтаксиса объявлений блока
  • Преобразование цели-c typedef в его эквивалент строки
  • Когда я должен использовать @synthesize явно?
  • Слабая переменная NSString не равна нулю после установки единственной сильной ссылки на nil
  • Как объявить массив слабых ссылок в Swift?
  • Вызов метода для неинициализированного объекта (нулевой указатель)
  • Измененный массив в области файлов
  • Как создать реальную переменную частного экземпляра?
  • ARC и мостовой литой
  • Как определить, являются ли методы Apple асинхронными?
  • Понимание побитового оператора AND
  • Давайте будем гением компьютера.