XML/HTML의 NSString을 인코딩합니다
-
03-07-2019 - |
문제
HTML이 객체 C에서 문자열 (nsstring)을 인코딩하는 방법이 있습니까? .net의 server.htmlencode 라인을 따라 무언가가 있습니까?
해결책
NSString 방법이 없습니다. 문자열 교체를 수행하는 자신의 기능을 작성해야합니다. 다음과 같은 교체를하기에 충분합니다.
- '&'=> "&"
- ' "'=>" ""
- '\'' => "'"
- '>'=> ">"
- '<'=> "<"
이와 같은 일은 (시도하지 않음) :
[[[[[myStr stringByReplacingOccurrencesOfString: @"&" withString: @"&"]
stringByReplacingOccurrencesOfString: @"\"" withString: @"""]
stringByReplacingOccurrencesOfString: @"'" withString: @"'"]
stringByReplacingOccurrencesOfString: @">" withString: @">"]
stringByReplacingOccurrencesOfString: @"<" withString: @"<"];
다른 팁
나는 Mike의 작업을 가져 와서 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];
}
* 신속한 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 Bridging 기능을 사용하여 NSString 버전과 매우 유사한 것을 작성할 수 있었지만 더 신중하기로 결정했습니다.
나는 사용한다 Mac 용 Google 도구 상자 (iPhone에서 작동). 특히 NSString in에 추가를 참조하십시오 gtmnsstring+html.h 그리고 gtmnsstring+xml.h.
URL 인코딩의 경우:
NSString * encodedString = [originalString
stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
보다 Apple의 NSString 문서 더 많은 정보를 위해서.
HTML 인코딩 용:
체크 아웃 cfxmlcreatestringbyescapingentities, 핵심 재단 XML 라이브러리의 일부이지만 여전히 트릭을 수행해야합니다.
Samets의 일상은 16 진수를 잊어 버렸습니다. 내가 그 일을 생각해 낸 일상은 다음과 같습니다.
- (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];
다음은 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 란 무엇입니까 :무엇을 하는가u003C![CDATA[]]> XML 의미에서?
Mike와 Tod의 답변을 사용하여 빠른 예제 프로젝트를 작성했습니다. 여기.
인코딩/인코딩을 단순하게 만듭니다.
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);
스위프트 4
extension String {
var xmlEscaped: String {
return replacingOccurrences(of: "&", with: "&")
.replacingOccurrences(of: "\"", with: """)
.replacingOccurrences(of: "'", with: "'")
.replacingOccurrences(of: ">", with: ">")
.replacingOccurrences(of: "<", with: "<")
}
}
이 가장 쉬운 솔루션은 다음과 같이 카테고리를 만드는 것입니다.
카테고리의 헤더 파일은 다음과 같습니다.
#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 번호의 전체 목록을 볼 수 있습니다.
내장 기능 만 사용하는 유일한 방법 (수동 구문 분석이 아님)을 발견하고 모든 경우를 다룹니다. 기초 외에도 AppKit/Uikit이 필요합니다. 이것은 신속하지만 객관적인 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!
}