【发布时间】:2012-07-28 22:51:57
【问题描述】:
我目前正在处理一个 iPad 项目,我需要将大型 XML 文件处理到 SQLite 后端。我目前正在使用TBXML 解析器进行这项工作。
所以所有的逻辑都已经到位,并且通常 TBXML 解析器完成了它需要完成的工作。我现在遇到的唯一问题是 XML 文件变得太大并且内存不足。因此,我考虑切换到像 Alan Quatermain 的 AQXMLParser 这样的核心 NSXMLParser 之类的 SAX 解析器。然而,这将要求我重做我当前的所有逻辑,这些逻辑在某种程度上依赖于 DOM 树提供的功能。这是我不想做的事情。
所以我想要尝试并做的是创建一种混合方法。鉴于我的 XML 结构,这应该是可能的。它基本上是一些重复的“记录”元素。在每条记录中都有可以重复和嵌套的各种元素。 在我目前的方法中,我解析文档并将每个记录元素传递给将其处理到数据库中的函数。鉴于这已经存在,我想在我的混合解析方法中使用它。
这就是我想要实现的。我使用 SAX 解析器遍历我的文档。在遍历文档时,我构建了一个 Record 元素。每当我完成一个记录元素时,我都会将它传递给使用 TBXML 处理它的现有函数。然后 SAX 解析器继续构建下一个记录元素。主要目标是: - 修复内存占用(它不需要尽可能小,但它必须是恒定的或至少比使用 TBXML 更小) - 保持性能可接受。
目前想实现如下:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{
//Recreate record string each time record element is encountered
if([elementName isEqualToString:@"Record"]) record = [[NSMutableString alloc] init];
//Write XML tag with name
[record appendFormat@"<%@>, elementName];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//Write XML content
[record appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//Write XML tag
[record appendFormat@"</%@>, elementName];
if([elementName isEqualToString:@"Record"]){
//Parse record string into TBXML object
TBXML * tbxmlRecord = [TBXML tbxmlWithXMLString:record];
//Send it to the TBXML record processor
[self processElement:tbxmlRecord.rootXMLElement];
}
}
我认为这应该可行,但使用字符串感觉很脏。此外,当解析器到达新的记录元素时,我担心记录字符串是否不会很快被覆盖。
所以我的问题是,如果这是解决此问题的合理方法,或者是否有更好的方法可以实现我正在寻找的目标?
编辑: 我已经实现了这种方法,它看起来工作得很好。我遇到的唯一问题是,如果我的源文件不是 UTF-8 编码的,我只会得到部分结果。但是当我纠正这一切时,一切顺利。内存使用并没有那么好。但也许它会尽其所能。需要运行更多测试...
【问题讨论】:
-
您的代码似乎有一些拼写错误。你能更新你的代码吗?会有帮助的
标签: objective-c dom xml-parsing sax tbxml