TinyXML2是一个开源、简单、小巧、高效的C++ XML解析器,它只有一个.h文件和一个.cpp文件组成,可以轻松集成到其它程序中。它解析XML文档并从中构建可以读取、修改和保存的文档对象模型(Document Object Model, DOM)。它不能解析DTD(Document Type Definitions, 文档类型定义)或XSL(eXtensible Stylesheet Language, 扩展样式表语言)。在TinyXML2中,XML数据被解析为可以浏览和操作的C++对象,然后写入磁盘和其它输出流。它不依赖于C++的STL。
TinyXML2的license为ZLib,可以商用,它的源码在https://github.com/leethomason/tinyxml2 ,最新发布版本为7.1.0。
关于XML的介绍可以参考:https://blog.csdn.net/fengbingchun/article/details/38978591
以下是测试代码(test_tinyxml2.cpp):创建XML(test_tinyxml2_create)和解析XML(test_tinyxml2_parse)
#include "funset.hpp"
#include <iostream>
#include "tinyxml2.h"int test_tinyxml2_create()
{const char* declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";tinyxml2::XMLDocument doc;tinyxml2::XMLError ret = doc.Parse(declaration);if (ret != 0) {fprintf(stderr, "fail to parse xml file: %s\n", declaration);return -1;}tinyxml2::XMLComment* comment = doc.NewComment("this is a xml test file");doc.InsertEndChild(comment);tinyxml2::XMLElement* root = doc.NewElement("Root");doc.InsertEndChild(root);// Usertinyxml2::XMLElement* user = doc.NewElement("User");user->SetAttribute("Name", "fengbingchun");root->InsertEndChild(user);tinyxml2::XMLElement* blog = doc.NewElement("Blog");tinyxml2::XMLText* text1 = doc.NewText("CSDN");blog->InsertEndChild(text1);user->InsertEndChild(blog);tinyxml2::XMLElement* code = doc.NewElement("Code");tinyxml2::XMLText* text2 = doc.NewText("GitHub");code->InsertEndChild(text2);user->InsertEndChild(code);// Blogtinyxml2::XMLElement* blog2 = doc.NewElement("Blog");blog2->SetAttribute("Name", "CSDN");root->InsertEndChild(blog2);tinyxml2::XMLElement* addr = doc.NewElement("Address");tinyxml2::XMLText* text3 = doc.NewText("https://blog.csdn.net/fengbingchun");addr->InsertEndChild(text3);blog2->InsertEndChild(addr);tinyxml2::XMLElement* id = doc.NewElement("ID");tinyxml2::XMLText* text4 = doc.NewText("fengbingchun");id->InsertEndChild(text4);blog2->InsertEndChild(id);// Codetinyxml2::XMLElement* code2 = doc.NewElement("Code");code2->SetAttribute("Name", "GitHub");root->InsertEndChild(code2);tinyxml2::XMLElement* addr2 = doc.NewElement("Address");tinyxml2::XMLText* text5 = doc.NewText("https://github.com//fengbingchun");addr2->InsertEndChild(text5);code2->InsertEndChild(addr2);tinyxml2::XMLElement* repositories = doc.NewElement("Repositories");tinyxml2::XMLText* text6 = doc.NewText("27");repositories->InsertEndChild(text6);code2->InsertEndChild(repositories);#ifdef _MSC_VERconst char* file_name = "E:/GitCode/Messy_Test/testdata/test.xml";
#elseconst char* file_name = "testdata/test.xml";
#endifret = doc.SaveFile(file_name);if (ret != 0) {fprintf(stderr, "fail to save xml file: %s\n", file_name);return -1;}return 0;
}int test_tinyxml2_parse()
{
#ifdef _MSC_VERconst char* file_name = "E:/GitCode/Messy_Test/testdata/test_tinyxml2.xml";
#elseconst char* file_name = "testdata/test_tinyxml2.xml";
#endiftinyxml2::XMLDocument doc;tinyxml2::XMLError ret = doc.LoadFile(file_name);if (ret != 0) {fprintf(stderr, "fail to load xml file: %s\n", file_name);return -1;}tinyxml2::XMLElement* root = doc.RootElement();fprintf(stdout, "root element name: %s\n", root->Name());// Usertinyxml2::XMLElement* user = root->FirstChildElement("User");if (!user) {fprintf(stderr, "no child element: User\n");return -1;}fprintf(stdout, "user name: %s\n", user->Attribute("Name"));tinyxml2::XMLElement* blog = user->FirstChildElement("Blog");if (!blog) {fprintf(stderr, "no child element: Blog, in User\n");return -1;}fprintf(stdout, "blog value: %s\n", blog->GetText());fprintf(stdout, "code value: %s\n\n", user->FirstChildElement("Code")->GetText());// Blogtinyxml2::XMLElement* blog2 = root->FirstChildElement("Blog");if (!blog2) {fprintf(stderr, "no child element: Blog\n");return -1;}fprintf(stdout, "blog name: %s\n", blog2->Attribute("Name"));tinyxml2::XMLElement* addr = blog2->FirstChildElement("Address");if (!addr) {fprintf(stderr, "no child element: Address, in Blog\n");return -1;}fprintf(stdout, "address value: %s\n", addr->GetText());fprintf(stdout, "id value: %s\n\n", blog2->FirstChildElement("ID")->GetText());// Codetinyxml2::XMLElement* code = root->FirstChildElement("Code");if (!code) {fprintf(stderr, "no child element: Code\n");return -1;}fprintf(stdout, "code name: %s\n", code->Attribute("Name"));tinyxml2::XMLElement* addr2 = code->FirstChildElement("Address");if (!addr2) {fprintf(stderr, "no child element: Address, in Code\n");return -1;}fprintf(stdout, "address value: %s\n", addr2->GetText());fprintf(stdout, "repositories value: %s\n\n", code->FirstChildElement("Repositories")->GetText());return 0;
}
创建xml文件的执行结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--this is a xml test file-->
<Root><User Name="fengbingchun"><Blog>CSDN</Blog><Code>GitHub</Code></User><Blog Name="CSDN"><Address>https://blog.csdn.net/fengbingchun</Address><ID>fengbingchun</ID></Blog><Code Name="GitHub"><Address>https://github.com//fengbingchun</Address><Repositories>27</Repositories></Code>
</Root>
解析以上xml文件输出结果如下:
GitHub:https://github.com/fengbingchun/Messy_Test