iOS:结合SAX和DOM解析
我目前正在研究一个iPad项目,我需要将大型XML文件处理为SQLite后端。我目前正在使用分析器TBXML工作。iOS:结合SAX和DOM解析
因此,所有的逻辑是在地方和一般的TBXML解析器做它需要做的工作。我现在遇到的唯一问题是XML文件变得太大,而且我的内存不足。因此,我考虑切换到像Alan Quatermain的AQXMLParser这样的核心NSXMLParser的SAX解析器。然而,这需要我重做所有当前的逻辑,这在某种程度上依赖于DOM树提供的功能。这是我不想做的事情。
所以我想什么尝试做的是创建一个混合的方法。鉴于我的XML结构,这应该是可能的。它基本上是一些重复的“记录”元素。并且在每条记录中都有可以重复和嵌套的各种元素。 在我目前的方法中,我解析文档并将每个记录元素传递给一个将其处理到数据库中的函数。鉴于这已经存在,我想在我的混合分析方法中使用它。
这就是我想要实现的。使用SAX解析器遍历我的文档。在遍历文档时,我构建了一个Record元素。每当我完成一个记录元素时,我将它传递给使用TBXML处理它的现有函数。 SAX解析器继续构建下一个记录元素。主要目标是: - 修复内存占用(它不需要到最小的也可以,但它必须是contstant或至少更小,使用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 [email protected]"<%@>, 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 [email protected]"</%@>, 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编码,我只能得到部分结果。但是,当我纠正这一切顺利。内存使用情况并不是那么好。但也许它需要什么。需要运行更多的测试...
一般来说你的方法听起来不错给我。如果你的解决方案在没有性能问题的情况下为你工作,那么我不会太担心字符串处理。如果你想要你可以分析你的应用程序,看看有多少CPU时间被这个浪费了。
如果您想做一些稍微更优化的事情,您可以尝试找到一个SAX解析器,该解析器为您提供原始缓冲区的字节偏移量,并将其与DOM解析器结合使用,从而可以使用非空字符结尾的C字符串。我相信这意味着你必须切换到C或C++库。我已经使用rapidxml来实现与你正在尝试的东西(嵌入在巨大文件中的xml块)类似的东西。
好吧,使用C(++)库不是我感到舒服的。所以我想我会实现这个版本,看看它是如何发展的。 – Deddiekoel 2012-07-31 08:09:56
我认为从性能的角度来看它可以,但要确保你能正确地逃避你的角色(即如果'>'出现在文本字符串中会发生什么情况)。另外,上面的代码片段不处理属性等,但我假设你可以控制输入。 – Krumelur 2012-07-31 08:12:10
XML本身非常简单。没有CDATA块(即使这不会成为问题,只是实现另一个委托方法)并且没有属性。逃避角色虽然是一个好点! – Deddiekoel 2012-07-31 08:26:29
看来你的代码有一些错别字。你能更新你的代码吗?这将是有益的 – Chrizzz 2012-09-10 14:12:22