对大文件有效的轻量级 XML 解析器?

Posted

技术标签:

【中文标题】对大文件有效的轻量级 XML 解析器?【英文标题】:A lightweight XML parser efficient for large files? 【发布时间】:2010-11-03 15:22:57 【问题描述】:

我需要解析潜在的巨大 XML 文件,所以我猜这排除了 DOM 解析器。

是否有任何适用于 C++ 的轻量级 SAX 解析器,可与 TinyXML 相媲美? XML 的结构非常简单,不需要像名称空间和 DTD 之类的高级东西。只是元素、属性和 cdata。

我知道 Xerces,但它超过 50mb 的绝对大小让我不寒而栗。

谢谢!

【问题讨论】:

***.com/questions/170686/best-open-xml-parser-for-c 【参考方案1】:

如果您使用的是 C,那么您可以使用来自 Gnome 项目的 LibXML。您可以为文档选择 DOM 和 SAX 接口,以及多年来开发的许多附加功能。如果你真的想要 C++,那么你可以使用 libxml++,它是一个 C++ OO 包装器,围绕着 LibXML。

该库已经一次又一次地被证明,具有高性能,并且几乎可以在您能找到的任何平台上编译。

【讨论】:

感谢您的回答。 LibXML 是轻量级的吗?它向可执行文件添加了多少 KB? 如果您使用的是动态库(UNIX 共享库/Windows DLL),那么答案是“无”。快速检查一下我的 Linux 框,显示共享库为 1.2M,静态库(用于编译程序)为 1.5M。因此,如果您进行静态编译,您将在您的 exe 中添加 1.5M-ish。 我的整个 .exe 大约 350Kb,所以我想我会愿意找到更轻量级的东西.. 不过还是谢谢 如果您真的担心大小,请在expat.sourceforge.net 尝试 Expat,我的 Linux 机器上的共享库大小为 133K。我猜在你的代码中静态编译的 .a 会是这么多。【参考方案2】:

我喜欢 ExPathttp://expat.sourceforge.net/

它是基于 C 的,但有几个 C++ 包装器可以提供帮助。

【讨论】:

【参考方案3】:

RapidXML 是一个非常快速的 C++ 编写的 XML 解析器。

【讨论】:

android 上崩溃。不能使用异常 这是一个 DOM 解析器,但它会“原地”解析,即它会更改源 XML 数据,因此您必须加载所有数据。【参考方案4】:

http://sourceforge.net/projects/wsdlpull 这是 java xmlpull api (http://www.xmlpull.org/) 的直接 c++ 端口

我强烈推荐这个解析器。我必须定制它以在我的嵌入式设备上使用(不支持 STL),但我发现它非常快且开销很小。我必须制作自己的字符串和向量类,即使在 Windows 上编译到大约 60k 的那些。

我认为拉式解析比 SAX 之类的更直观。代码更紧密地反映了 xml 文档,因此很容易将两者关联起来。

一个缺点是它只是向前的,这意味着您需要在元素到来时对其进行解析。我们有一个相当混乱的设计来读取我们的配置文件,我需要解析整个子树,进行一些检查,然后设置一些默认值,然后再次解析。使用此解析器,处理此类事情的唯一真正方法是制作状态副本,用它进行解析,然后继续使用原始状态。与我们的旧 DOM 解析器相比,它在资源方面仍然是一个巨大的胜利。

【讨论】:

它一次解析一个字符,并为该字符使用一个 int。对于元素属性名称,它对有效标识符的定义(基本上是ascii)有相当严格的定义,但更改它可能不需要太多。它带有一个进行解析/序列化测试的项目,因此很容易在一些代表性数据上运行它来进行尝试。 感谢您的回答,我会调查一下【参考方案5】:

如果您的 XML 结构非常简单,您可以考虑基于 lex/yacc (flex/bison) 构建一个简单的词法分析器/扫描器。 W3C 的资源可能会启发您:http://www.w3.org/XML/9707/parser.y 和 http://www.w3.org/XML/9707/scanner.l。

另请参阅SAX2 interface in libxml

【讨论】:

【参考方案6】:

firstobject 的CMarkup 是一个C++ 类,它可以作为一个轻量级的大文件拉解析器(我推荐拉解析器而不是SAX)和大的XML 文件编写器。它为您的可执行文件添加了大约 250kb。根据一位用户的报告,当在内存中使用时,它的占用空间是 tinyxml 的 1/3。当用于大文件时,它只在内存中保存一个小缓冲区(如 16kb)。 CMarkup 目前是一种商业产品,因此它受到支持、记录和设计,可以通过单个 cpp 和 h 文件轻松添加到您的项目中。

最简单的尝试方法是使用免费的 firstobject XML 编辑器中的脚本,例如:

ParseHugeXmlFile()

  C标记xml;
  xml.Open("HugeFile.xml", MDF_READFILE);
  while ( xml.FindElem("//record") )
  
    // 进程记录...
    str sRecordId = xml.GetAttrib("id");
    xml.IntoElem();
    xml.FindElem("描述");
    str sDescription = xml.GetData();
  
  xml.关闭();

从“文件”菜单中,选择“新建程序”,将其粘贴进去并针对您的元素和属性进行修改,按 F9 运行它或按 F10 逐行执行。

【讨论】:

【参考方案7】:

你可以试试https://github.com/thinlizzy/die-xml。它似乎很小且易于使用

这是一个最近开源的C++0x XML SAX解析器,作者愿意反馈

它解析输入流并在与 std::function 兼容的回调上生成事件

堆栈机器使用有限自动机作为后端,并且一些事件(开始标记和文本节点)使用迭代器来最小化缓冲,使其非常轻量级

【讨论】:

【参考方案8】:

如果您想要小而快,我会查看 generate a DTD/Schema-specific parser 的工具。这些对于大型文档非常有用。

【讨论】:

【参考方案9】:

我强烈推荐pugixml

pugixml 是一个轻量级的 C++ XML 处理库。

"pugixml 是一个 C++ XML 处理库,它由一个具有丰富遍历/修改能力的类 DOM 接口、一个从 XML 文件/缓冲区构造 DOM 树的极快的 XML 解析器和一个 XPath 组成1.0 实现复杂的数据驱动树查询。还提供完整的 Unicode 支持,包括 Unicode 接口变体和不同 Unicode 编码之间的转换。"

在选择并在商业产品中使用 pugixml 之前,我已经测试了一些 XML 解析器,包括一些昂贵的解析器。

pugixml 不仅是最快的解析器,而且拥有最成熟和友好的 API。我强烈推荐它。是非常稳定的产品!我从 0.8 版开始使用它。现在是 1.7。

这个解析器的最大好处是 XPath 1.0 实现!对于任何更复杂的树查询,XPath 都是上帝派来的功能!

具有丰富遍历/修改功能的类 DOM 界面对于处理现实生活中“繁重”的 XML 文件非常有用。

它是小型、快速的解析器。如果您不介意链接 C++ 代码,即使对于 ios 或 Android 应用程序也是不错的选择。

基准可以说明很多。见:http://pugixml.org/benchmark.html

(x86) 的几个例子:

pugixml is more than 38 times faster than TinyXML

                    4.1 times faster than CMarkup,

                    2.7 times faster than expat or libxml

For (x64) pugixml 是我所知道的最快的解析器。

还要检查您的 XML 解析器对内存的使用情况。一些解析器只是吞噬宝贵的内存!

【讨论】:

问题要求使用 SAX 解析器。将超大的 XML 文件加载到 DOM 结构中并不可行。

以上是关于对大文件有效的轻量级 XML 解析器?的主要内容,如果未能解决你的问题,请参考以下文章

XML

解析器:分隔符指导

在 laravel 中解析 XML 文件

day02-解析器

解析XML文件之使用SAM解析器

使用DOM解析器解析XML文件 学习笔记