C++中的高性能XML解析

And*_*dry 9 c++ xml parsing

关于在C++中解析XML等问题已经提出了很多问题......但是,我的问题非常具体,而不是一般问题.

我要求一个非常有效的C++ XML解析器.特别是我有一个非常非常大的XML文件来解析.我的应用程序必须打开此文件并检索数据.它还必须插入新节点并再次将最终结果保存在文件中.

为了做到这一点,我在开始时使用了rapidxml,但它要求我打开文件,解析所有内容(所有内容因为这个lib没有直接访问文件的功能而不先加载整个树),然后编辑树,修改它并通过覆盖它将最终树存储在文件上...它消耗了太多的资源.

是否有一个XML解析器,不需要我加载整个文件,但我可以用来快速插入新节点和检索数据?你能指出我这个问题的解决方案吗?

Dan*_*ien 10

您需要流式XML解析器而不是所谓的DOM解析器.

有两种类型的流解析器:拉和推.pull解析器适用于快速编写将数据加载到程序存储器中的XML解析器.推送解析器适用于编写程序以将一个文档转换为另一个文档(这是您要完成的任务).因此,我认为推送解析器最适合您的问题.

为了使用推送解析器,您需要编写本质上是用于解析事件的事件处理程序.通过"解析事件",我的意思是"达到开始标记","达到结束标记","找到文本","解析属性"等事件.

我建议您在阅读文档时,将转换后的文档写入单独的临时文件.因此,您需要编写XML解析事件处理程序,以便它们是有状态的,并逐步写出已翻译文档的XML.

C++的三个优秀推送解析器库包括Expat,Xerces-C++libxml2.

  • 无论您使用pull或push SAX解析器,最终结果都是相同的.两者都需要在以块为单位解析XML数据时使用事件处理程序.它们之间的唯一区别是拉解析器会自动从您指定的源(如文件)中检索数据,而推送解析器允许您自己获取数据并将其传递给解析器(在这方面,拉解析器使用内部推模型).两个解析器都有相同类型的内部逻辑 - 给定一大块数据,解析它并根据需要触发事件,然后拉/等下一个块并重复... (2认同)
  • ...因此,您的SAX事件处理程序可以在以块为单位解析XML时实时提取数据,然后您可以将提供的数据写入临时文件,在需要时写入新数据,然后替换完成后带有临时文件的原始文件. (2认同)

Eug*_*its 5

搜索"SAX解析器".它们大多是标记化器,即它们不依赖标记而不构建树.


Dav*_*ser 5

SAX 解析器比 DOM 解析器更快,因为 DOM 解析器在构建 XML 文档的内存中表示之前将整个文件读入内存,而 SAX 解析器的行为类似于事件侦听器,并在读入文件时构建文档。去这里寻求解释。

正如您提到的,Xerces是一个很好的 C++ SAX 解析器。

我建议研究将 XML 文档分解为更小的 XML 文档的方法,因为这似乎是您问题的一部分。


Nim*_*Nim 5

好吧,这是一个人迹罕至的地方,我看了这个,但自己还没有真正使用过它,它叫做asmxml。这些男孩声称性能无可挑剔,但缺点是,您需要 x86 汇编器。

  • @downvoter,请解释一下?我只是强调一个不寻常的解析器,它声称比大多数主要解析器有更好的性能,我所说的有什么问题吗? (2认同)