TinyXML2的快速实践
程序员文章站
2022-06-17 08:12:17
最近遇到个需要在C++中处理XML文件的需求,虽然对此方面并不是很熟,但好在有GitHub上的 "awesome cpp" 项目的帮助,还是收获了足够的相关知识。 类库 常用的或被推荐的XML类库有以下数个选项,不过相较于纯C完成的类库个人还是更倾向于C++的类库: Boost.PropertyTr ......
最近遇到个需要在c++中处理xml文件的需求,虽然对此方面并不是很熟,但好在有github上的项目的帮助,还是收获了足够的相关知识。
类库
常用的或被推荐的xml类库有以下数个选项,不过相较于纯c完成的类库个人还是更倾向于c++的类库:
- boost.propertytree - a property tree parser/generator that can be used to parse xml/json/ini/info files. [boost]
- expat - an xml parser library written in c. [mit]
- libxml2 - the xml c parser and toolkit of gnome. [mit]
- libxml++ - an xml parser for c++. [lgpl2]
- mini-xml - a small xml parsing library written in ansi c. [lgpl2 with exceptions]
- pugixml - a light-weight, simple and fast xml parser for c++ with xpath support. [mit]
- rapidxml - an attempt to create the fastest xml parser possible, while retaining useability, portability and reasonable w3c compatibility. [boost]
- tinyxml - a simple, small, minimal, c++ xml parser that can be easily integrating into other programs. [zlib]
- tinyxml2 - a simple, small, efficient, c++ xml parser that can be easily integrating into other programs. [zlib]
- tinyxml++ - a completely new interface to tinyxml that uses many of the c++ strengths. templates, exceptions, and much better error handling. [mit]
- xerces-c++ - a validating xml parser written in a portable subset of c++. [apache2]
tinyxml vs tinyxml2
tinyxml是在寻找更多信息时被多次提及的,因为并不想花费过多时间在做选择题上,于是其似乎成了最终的赢家。
但未曾想它自身还有两个版本。
tinyxml与tinyxml2的相同点:
- 简单的api
- 基于dom的解析器
- 支持utf-8 unicode
tinyxml2的优点:
- 着眼于未来的开发
- 更少的内存分配(1/10到1/100),使用更少的内存(tinyxml的40%),更快(读取上约5倍)
- 不再需要stl
- 更现代的c++,包括一个合适的命名空间
- 适当且有用地处理空白
tinyxml的优点:
- 能够报告解析错误的位置
- 支持一些c++ stl约定:流与字符串
- 非常成熟并且调试良好的代码库
tinyxml2的第2及第4项优点是我更中意的,所以还是选它吧。
使用方法
在其github的仓库中下载相关文件,
找到tinyxml2.h与tinyxml2.cpp两个文件,将它们添加至你的工程项目中,这便是所有需要的。
示例
#include <iostream> #include <random> #include "tinyxml2.h" using namespace tinyxml2; void writexmlfile() { xmldocument doc; auto delaration = doc.newdeclaration(); doc.insertfirstchild(delaration); auto root = doc.newelement("root"); doc.insertendchild(root); auto id = doc.newelement("id"); id->settext(666); root->insertendchild(id); auto name = doc.newelement("name"); name->settext("ken"); name->setattribute("blogger", true); root->insertendchild(name); doc.savefile("sample.xml"); } xmldocument* readxmlfile() { auto doc = new xmldocument; doc->loadfile("sample.xml"); auto root = doc->rootelement(); auto id = root->firstchildelement("id"); std::cout << id->gettext() << std::endl; auto name = root->firstchildelement("name"); std::cout << name->gettext() << std::endl; std::cout << name->attribute("blogger") << std::endl; return doc; } int main() { writexmlfile(); auto doc = readxmlfile(); auto root = doc->rootelement(); auto id = root->firstchildelement("id"); doc->deletenode(id); auto randomid = doc->newelement("randomid"); std::default_random_engine e; std::uniform_int_distribution<int> u; auto r = u(e, decltype(u)::param_type(1000000, 9000000)); randomid->settext(r); root->insertfirstchild(randomid); doc->print(); delete doc; }