什么是最好的用于C++的开放式XML解析器?

250
我正在寻找一个简单、干净、正确的XML解析器来在我的C++项目中使用。我应该自己编写吗?

3
注意:有一个关于如何选择用于C++的XML解析器的问题。链接在此:https://dev59.com/PGox5IYBdhLWcg3wKBR9。 - Nicol Bolas
1
正如@NicolBolas所指出的那样,现在有一个更近期的StackOverflow帖子问了同样的问题:https://dev59.com/PGox5IYBdhLWcg3wKBR9 - Dan Nissenbaum
3
请注意,我参考的最新的StackOverflow帖子(截至2014年12月)几乎有与当前问题一样多的赞,而答案比这里的答案获得了更多的赞,并且有一个非常棒、易于阅读的流程图。 - Dan Nissenbaum
12个回答

124

你听说过RapidXML吗?RapidXML是一个非常快速且小巧的C++ XML DOM解析器。它主要针对嵌入式环境、电脑游戏或任何需要优化可用内存或CPU处理能力的应用程序。RapidXML在Boost软件许可下授权,并且其源代码可以免费获取。

特点

  • 解析速度(包括DOM树构建)接近于执行相同数据上的strlen函数的速度。
  • 在现代CPU(截至2008年),解析器吞吐量约为每秒10亿个字符。请参阅在线手册中的性能部分。
  • 代码和创建的DOM树的内存占用很小。
  • 只有头文件的实现,简化了集成过程。
  • 简单的许可证允许在几乎任何商业和非商业目的下使用,而不需要任何义务。
  • 支持UTF-8和部分UTF-16、UTF-32编码。
  • 便携式源代码,除了非常小的C++标准库子集之外没有其他依赖项。
  • 这个子集非常小,如果不想使用标准库,则可以轻松手动模拟。

限制

  • 解析器忽略DOCTYPE声明。
  • 不支持XML命名空间。
  • 解析器不检查字符的有效性。
  • 解析器的接口不符合DOM规范。
  • 解析器不检查属性的唯一性。

来源:wikipedia.org://Rapidxml


根据您的使用情况,您可能会使用XML数据绑定。CodeSynthesis XSD是由Code Synthesis开发的用于C ++的XML数据绑定编译器,双重许可证为GNU GPL和专有许可证。给定一个XML实例规范(XML模式),它将生成表示给定词汇表的C ++类以及解析和序列化代码。
CodeSynthesis XSD的独特功能之一是其支持两种不同的XML模式到C ++映射:内存中的C ++ / Tree和面向流的C ++ / Parser。 C ++ / Tree映射是传统映射,具有类似树形的内存数据结构。 C ++ / Parser是一种新的、类似SAX的映射,它将存储在XML实例文档中的信息表示为特定于词汇表的解析事件层次结构。与C ++ / Tree相比,C ++ / Parser映射允许处理无法放入内存的大型XML文档、执行面向流的处理或使用现有的内存表示。
来源: wikipedia.org://CodeSynthesis XSD

7
我喜欢仅使用头文件的方法(我认为你只需要一个头文件)。只需将其放入项目中,无需担心更改构建过程中的任何内容。 - Frank
7
如果“解析器不检查字符的有效性”和“解析器不检查属性的唯一性”,严格来说,它就不是一个XML解析器——这些不是可选检查,而是由XML规范本身强制要求的。我不会浪费时间在这样的事情上,因为实际上还有真正好的解析器(例如libxml2)。 - StaxMan
3
这就是我使用Rapidxml的原因。我所处理的一个系统坚持在元素名称后面添加非法的空格,而Rapidxml是唯一能够处理这种情况的解析器(尽管它不会注意到这个问题!) - Martin Beckett
1
Rapidxml拥有许多实现XML的功能,就像MSXML一样。但是与其他解析器相比,节点遍历非常困难...还有文件读写... - Rajakumar
1
在选择用于商业用途(在某种特定领域内)的 XML 解析器时,我们需要看看该解析器是否将得到至少 2 到 3 十年的维护。像 Xerces 这样的解析器似乎更有可能得到支持和维护,而不是 RapidXML。那么使用 RapidXML 是否明智呢? - Nav
显示剩余6条评论

114

pugixml 是一个轻量级、简单且快速的 C++ XML 解析器。它非常小(与 RapidXML 相当),非常快(与 RapidXML 相当),非常易于使用( RapidXML 更好)。


28
哇,这是很多要求。你能证明这些吗?在这些领域中,它有什么优势?有参考文章吗? - Kissaki
4
阅读了一些有关RapidXML和pugixml网站的内容后,我(可能)明白了你的意思。RapidXML基于/受到pugixml的启发。它在解析方面的文档很少。pugixml在解析方面具有良好的文档和易用的API。(到目前为止只阅读了解析部分的内容。) - Kissaki
1
Pugixml使用起来要容易得多,比如读取XML文件 - 只需load_file("file.xml")!我发现它比rapid_xml更直观。通过xpath选择节点也非常不错。 - aurel
pugixml是一个非常优秀的软件包。尽管公正地说,文档组合API有点笨拙(虽然这个批评几乎适用于我见过的每个软件包!),但Xpath支持是一个巨大的优势。 - arayq2
2
@Kissaki 我在使用pugixml商业产品之前测试了几个XML解析器,包括一些商业解析器。 - sg7
显示剩余3条评论

43

2
在VC++和eVC++中多次使用了tinyXML - 总是运行良好。 - JohnIdol
4
请使用TinyXML 2 http://www.grinninglizard.com/tinyxml2/index.html。 - KindDragon
我正在尝试这个,但是从tinyxml2调用的类出现了未解决的错误。有什么想法吗?我在包含的头文件中找到了这些类,所以它们应该是可用的。 - backend_dev_123
我已经拒绝使用这个库(也检查了TinyXML2),因为该库没有提供从Unicode路径名加载的功能。此外,目前我更喜欢可用性和完整实现而不是性能。 - TarmoPikaro
@KindDragon,那个链接已经失效了(“账户被暂停”,哎!) - underscore_d
https://github.com/leethomason/tinyxml2 - KindDragon

16

TiCPP是TinyXML的“更多C ++”版本。

'TiCPP' 是 TinyXML++ 的官方名称,它是对 TinyXML (http://www.grinninglizard.com/tinyxml/) 的全新接口,利用了许多 C++ 的优势。包括模板、异常和更好的错误处理。它在 doxygen 中也有完整的文档。这个版本非常棒,因为它让你可以像以前一样与 TinyXML 进行交互,或者选择使用新的 'ticpp' 类。你所需要做的就是定义 TIXML_USE_TICPP。它已在 VC 6.0、VC 7.0、VC 7.1、VC 8.0、MinGW gcc 3.4.5 和 Linux GNU gcc 3+ 中进行了测试。


这里的 TiCPP 链接建议使用这个链接,而 tinyxml 的链接已经失效了(“账户被暂停”,哎呀!) - underscore_d

14

1
他们制作了一个更新的版本:http://www.applied-mathematics.net/tools/IXMLParser.html - Andrew
3
仅作提醒,对于像我这样正在查看的人:较新版本的许可证非常奇怪,你甚至无法在未发送电子邮件之前下载它。我想我会选择pugixml。 - Andrew

12

如果你关心效率/内存管理,不要使用 TinyXML(它倾向于分配很多小块)。我个人最喜欢的是 RapidXML


10

你觉得 gSOAP 怎么样?它是开源的,并在 GPL 许可下免费提供。尽管它的名称是 gSOAP 工具包,但它是一个通用的 XML 数据绑定工具,可以让您自动将 C 和 C++ 数据绑定到 XML。无需使用 XML 解析器 API,只需让它为您读/写 XML 格式的数据即可。如果您真的需要一个超级简单的 C++ XML 解析器,那么 gSOAP 可能会过于臃肿。但对于其他所有东西,自 2001 年推出以来,根据用户反馈,gSOAP 在许多工业应用中都表现良好。

以下是一些功能的简要列表:

  • 可移植性强:支持Windows、Linux、Mac OS X、Unix、VxWorks、Symbian、Palm OS、WinCE等多种操作系统。
  • 占用空间小:仅73KB的代码和不到2K的数据即可实现XML Web服务客户端应用程序(无DOM限制内存使用)。
  • 速度快:不要相信其他工具所声称的速度,真正的速度应该是在I/O的情况下进行测量。对于gSOAP而言,在TCP/IP上进行3000次往返的XML消息传递速度非常快。由于XML解析开销可以忽略不计,因为它只是对输入/输出进行简单的线性扫描,而(反)序列化则同时进行。
  • XML支持:支持XML模式(XSD)导入/导出、WSDL导入/导出、XML命名空间、XML规范化、带附件的XML(MIME)、可选使用DOM、许多选项以产生带缩进的XML、使用UTF8字符串等。
  • XML验证:部分和完全(可选)
  • WS支持:WS-Security、WS-ReliableMessaging、WS-Addressing、WS-Policy、WS-SecurityPolicy等。
  • 调试:集成了内存管理和泄漏检测、日志记录等功能。
  • API:无需学习API,只需进行“soap”引擎上下文初始化,然后使用读/写接口处理数据,最后进行“soap”引擎上下文销毁即可。

例如:

class Address
{ 
  std::string name;
  std::vector<LONG64> number;
  time_t date;
};

然后在上面的Address类声明上运行"soapcpp2",以生成soap_read_Addresssoap_write_Address XML读取器和写入器,例如:

Address *a = new Address();
a = ...;
soap ctx = soap_new();
soap_write_Address(ctx, a);
soap_end(ctx);
soap_free(ctx);`

这将生成一个Address a对象的XML表示。通过在头文件声明中注释XML命名空间细节(此处未显示),工具还会生成模式。这是一个简单的例子。gSOAP工具可以处理非常广泛的C和C++数据类型,包括基于指针的链接结构,甚至是(循环)图形(而不仅仅是树)。

希望这有所帮助。


3
商业使用需支付一次性费用以使用gSoap。 - Nayana Adassuriya

9

我是一个C++的新手,在尝试了这个页面上的几个不同建议后,我必须说我最喜欢的是pugixml。它有易于理解的文档和高级API,这正是我所需要的。


9
TinyXML适用于简单的XML工作,但如果需要更多功能,请尝试来自Apache项目的Xerces。请访问以下页面了解其更多功能。

http://xerces.apache.org/xerces-c/


Xerces有哪些TinyXML没有的功能? - whaledawg
好的,更重要的是,TinyXML缺少哪些功能? - whaledawg
它实现了整个DOM。TinyXML更简单,但足以保留XML中的数据。 - Lev
4
Xerces 实现了完整的 XML 标准。TinyXML 只实现了足够有用的部分。事实证明,99% 的用户只会使用 XML 标准的 1%,因此 TinyXML 通常已经足够了。 - deft_code

9
TinyXML和Boost.PropertyTree。后者不符合所有官方要求,但非常简单。

2
Boost.PropertyTree非常适合我的简单数据存储需求。这个页面清晰地展示了如何使用它。哇,我喜欢Boost。 - Olical
1
Boost PropertyTree 在除了一些简单的 XML 文件之外并不是很有用。该结构没有反向链接,因此要获取节点的父级,意味着您真的需要自己编写数据结构来存储 Property Tree 读取后的 XML。而且它没有类似 xpath 的查询支持。您只能轻松地将 XML 文件读入树形结构中,并在知道确切路径的情况下直接提取值。 - Minok
我也喜欢boost::property_tree。这里有一些实用的Visual Studio实现如何解析XML和JSON - AndyUK
1
boost::property_tree 很臃肿(增加编译时间和可执行文件大小),而且似乎已经没有人维护了。不建议使用。 - Andreas Haferburg
我已经拒绝使用这个库(也检查了TinyXML2),因为该库没有提供从Unicode路径名加载的功能。此外,目前我更喜欢可用性和完整实现而不是性能。 - TarmoPikaro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接