Cra*_*tis 5 xml cocoa encoding parsing objective-c
我使用Apple的NSXMLParser类来加载数据.我有一个单独的框架来序列化我的数据.
我已经有足够的长字符,Word引号等出现在我的XML输出中并在解析时导致错误,这通常会导致数据丢失,因为解析器对这些字符的处理不当.
如果我将用户的输入作为NSString对象,我想将其转换为Base64(我有一个实用工具方法),然后将这些字节写入XML文件,代替NSString.我知道这可能会占用更多空间,但至少我不再需要处理验证问题了.
我的问题是,如何将NSData字节(看起来像<8d72...>在NSLog语句中)转换为NSString,而不使用编码来获取原始值.我希望将那些出现在日志语句中的实际字节转换为NSString.最后(加载此序列化数据时),如果您有NSString:
NSString *loadedData = @"8d72...";
Run Code Online (Sandbox Code Playgroud)
如何从这种形式转变为人类可读的格式?整个编码过程对我来说有点难以理解,但我认为这是确保在我的XML文件中正确保留奇怪的用户输入的一种非常可靠的方法.
Cra*_*tis 11
得到它了.我正在使用此答案中的编码/解码方法将我的NSString对象转换为NSData对象,反之亦然: iphone-sdk上的任何base64库?
然后我编写了这些使用上述方法的快速方法,并允许我将Base64字符串数据写入XML.加载效果很好,已经过中文字符,单词字符等测试.如果需要,也可以解析这些,但至少错误不在解析器中.(如果您没有正确处理错误,很容易导致数据丢失.)
+ (NSString *)toBase64String:(NSString *)string {
NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding];
NSString *ret = [NSStringUtil base64StringFromData:data length:[data length]];
return ret;
}
+ (NSString *)fromBase64String:(NSString *)string {
NSData *base64Data = [NSStringUtil base64DataFromString:string];
NSString* decryptedStr = [[NSString alloc] initWithData:base64Data encoding:NSUnicodeStringEncoding];
return [decryptedStr autorelease];
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于原始链接已关闭,我从前一段时间开始搜索我的代码,这是我NSStringUtil上面提到的方法.注意我没有编写此代码,但多年来一直运行良好:
+ (NSData *)base64DataFromString: (NSString *)string {
unsigned long ixtext, lentext;
unsigned char ch, input[4], output[3];
short i, ixinput;
Boolean flignore, flendtext = false;
const char *temporary;
NSMutableData *result;
if (!string) {
return [NSData data];
}
ixtext = 0;
temporary = [string UTF8String];
lentext = [string length];
result = [NSMutableData dataWithCapacity: lentext];
ixinput = 0;
while (true) {
if (ixtext >= lentext) {
break;
}
ch = temporary[ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z')) {
ch = ch - 'A';
} else if ((ch >= 'a') && (ch <= 'z')) {
ch = ch - 'a' + 26;
} else if ((ch >= '0') && (ch <= '9')) {
ch = ch - '0' + 52;
} else if (ch == '+') {
ch = 62;
} else if (ch == '=') {
flendtext = true;
} else if (ch == '/') {
ch = 63;
} else {
flignore = true;
}
if (!flignore) {
short ctcharsinput = 3;
Boolean flbreak = false;
if (flendtext) {
if (ixinput == 0) {
break;
}
if ((ixinput == 1) || (ixinput == 2)) {
ctcharsinput = 1;
} else {
ctcharsinput = 2;
}
ixinput = 3;
flbreak = true;
}
input[ixinput++] = ch;
if (ixinput == 4) {
ixinput = 0;
unsigned char0 = input[0];
unsigned char1 = input[1];
unsigned char2 = input[2];
unsigned char3 = input[3];
output[0] = (char0 << 2) | ((char1 & 0x30) >> 4);
output[1] = ((char1 & 0x0F) << 4) | ((char2 & 0x3C) >> 2);
output[2] = ((char2 & 0x03) << 6) | (char3 & 0x3F);
for (i = 0; i < ctcharsinput; i++) {
[result appendBytes: &output[i] length: 1];
}
}
if (flbreak) {
break;
}
}
}
return result;
}
+ (NSString *)base64StringFromData: (NSData *)data length: (NSUInteger)length {
unsigned long ixtext, lentext;
long ctremaining;
unsigned char input[3], output[4];
short i, charsonline = 0, ctcopy;
const unsigned char *raw;
NSMutableString *result;
lentext = [data length];
if (lentext < 1) {
return @"";
}
result = [NSMutableString stringWithCapacity: lentext];
raw = [data bytes];
ixtext = 0;
while (true) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0) {
break;
}
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext) {
input[i] = raw[ix];
} else {
input[i] = 0;
}
}
output[0] = (input[0] & 0xFC) >> 2;
output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
output[3] = input[2] & 0x3F;
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++) {
[result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];
}
for (i = ctcopy; i < 4; i++) {
[result appendString: @"="];
}
ixtext += 3;
charsonline += 4;
if ((ixtext % 90) == 0) {
[result appendString: @"\n"];
}
if (length > 0) {
if (charsonline >= length) {
charsonline = 0;
[result appendString: @"\n"];
}
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)