我正在解析一个xml文件,我一直试图去除currentElementValue中的空白字符,因为它搞乱了一些事情。
我可以在输出窗口中看到有几个回车和标签存在
(gdb) po string
Keep the arms on the side, and lift your leg.
(gdb) po currentElementValue
Keep the arms on the side, and lift your leg.
(gdb)
这是我的foundCharacters函数,但我一直试图使用stringByTrimmingCharactersInSet但没有成功。
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
{
[currentElementValue appendString:string];
currentElementValue = [currentElementValue stringByTrimmingCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
NSString *instructions = @"instructions";
[directions setValue:string forKey:instructions]; //mm
[appDelegate.directions setValue:string forKey:instructions];
//[appDelegate.directions setObject:string forKey:currentElementValue];
// [appDelegate
}
}
我一直在收到这个错误 ***由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'尝试使用appendString来改变不可变对象:' 这很奇怪,因为我的currentElementValue是一个NSMutableString .. 出了什么问题?有没有人有线索或想法?
答案 0 :(得分:7)
让我们一步一步,找到你的错误,并解决内存泄漏问题:
首先,创建一个NSMutableString。大。 (+1保留计数)
然后将另一个字符串附加到NSMutableString上。没关系。 (仍然+1保留计数)。
然后你修剪newlineCharacterSet,它返回一个自动释放的NSString。由于此对象与原始对象不同,因此您泄漏了原始对象(因为它具有+1保留计数而您不再有指向它的指针),并且您现在有一个不可变的NSString可以引导。这意味着下次调用此方法时,您将尝试将一个字符串附加到NSString上,这将抛出“无法改变不可变对象”异常。
以下是解决此问题的快捷方法:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
{
[currentElementValue appendString:string];
NSString *trimmedString = [currentElementValue stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
[currentElementValue setString:trimmedString];
NSString *instructions = @"instructions";
[directions setValue:string forKey:instructions]; //mm
[appDelegate.directions setValue:string forKey:instructions];
//[appDelegate.directions setObject:string forKey:currentElementValue];
// [appDelegate
}
}
(将修剪过的字符串保存到另一个变量,然后使用NSMutableString的setString:方法传入内容,但不会丢失指向NSMutableString的指针)
答案 1 :(得分:0)
顺便说一句......我认为NSXMLParser应该提供处理空白的设置,即在XML / XSLT的W3.org规范中“保留空白” - 此外,我不想得到适合像修剪一样的字符集。基本上,我希望像在XML / XMSLT转换中那样访问“@text()”。所以,我做了一些挖掘并发现了这种方法。请注意,可以将空白字符串附加到累积的文本。在第一次尝试它不起作用,但我有更多的实验要做,并仔细检查我的语法(即,削减'n粘贴技能:))
- (void)parser:(NSXMLParser *)parser foundIgnorableWhitespace:(NSString *)whitespaceString
<强>参数:强> 解析器 解析器对象。
whitespaceString 一个字符串,表示当前元素的全部或部分可忽略的空白字符。
<强>讨论强> 可能无法通过单独调用此方法来提供元素的所有空白字符(包括回车符,制表符和换行符)。解析器可以向委托发送几个解析器:foundIgnorableWhitespace:消息来报告元素的空白字符。您应该将每次调用中的字符追加到当前的字符累积中。
答案 2 :(得分:0)
我找到了一种处理节点文本的简洁方法。它假定您拥有XML内容/格式的所有权。我现在正在做的是使用CDATA部分作为我的节点的“text()”属性。这不包括我用来制作我的xml文档的空格。
要阅读的代码如下:
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock {
NSLog(@"%s", __FUNCTION__);
NSLog(@"[%@]", CDATABlock);
NSString *strData = [[NSString alloc] initWithData:CDATABlock encoding: NSUTF8StringEncoding ];
NSLog(@"convertToString=[%@]", strData);
}
并且XML片段是这样的(带有'着名引号'的教程):
<quote><![CDATA[And in the end...in your years.]]></quote>
并且跟踪输出如下:
2009-11-21 13:17:51.901 Fate[2241:4203] -[XMLReader parser:foundCDATA:]
2009-11-21 13:17:51.901 Fate[2241:4203] [<416e6420 696e2074 68652065 6e642c20 69742773 206e6f74 20746865 20796561 72732069 6e20796f 7572206c 69666520 74686174 20636f75 6e742e20 20497427 73207468 65206c69 66652069 6e20796f 75722079 65617273 2e>]
2009-11-21 13:17:55.774 Fate[2241:4203] convertToString=[And in the end, it's not the years in your life that count. It's the life in your years.]]>
答案 3 :(得分:0)
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Removing whitspace and newline characters
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// If no characters are left return
if([string length] == 0) return;
//Rest of the code for saving the string