tinyxml2使用学习

平时做c/c++开发时经常需要解析xml文件,linux一般就用libxml2做,但是更多时候写的代码需要在linx下跑也要在windows下跑,即使在windows有可能是vc写的还有可能是qt写的。这时解析xml就不那么方便。这里推荐一个tinyxml2开源库,使用了它,解析xml会轻松很多。

tinyxml2的使用比较简单,从官网指定的github地址上下载两个文件(tinyxml2.h、tinyxml2.cpp),然后项目中用到时加入就行了。

这篇文章直接上一个实例,通过这个实例应该可以学会如何使用tinyxml2进行xml的常用操作。

道生一,一生二,二生三,三生万物

废话少说,直接贴代码。

这是提前写好的xml文件:user.xml

1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<users>
<user name="aaa" age="33"/>
<user name="bbb" age="22"/>
</users>

这是实例代码文件:test1.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <stdio.h>
#include <iostream>
#include "tinyxml2.h"

using namespace tinyxml2;
using namespace std;

int main()
{
cout<<"tinyxml2 test1."<<endl;
cout<<"--------------------------"<<endl;
cout<<"read from file."<<endl;
cout<<"--------------------------"<<endl;
XMLDocument doc;
if (doc.LoadFile("./user.xml") != 0) {
cout<<"load xml file failed."<<endl;
return 1;
}
doc.Print();
cout<<"--------------------------"<<endl;
cout<<"read from memory."<<endl;
cout<<"--------------------------"<<endl;
FILE *fp = fopen("user.xml", "r");
if (fp == NULL) {
cout<<"open file failed."<<endl;
return 1;
}
fseek(fp, 0, SEEK_END);
int len = ftell(fp);
cout<<"file length is "<<len<<endl;
char *buf = (char*)malloc(len+1);
memset(buf, 0, len+1);
fseek(fp, 0, SEEK_SET);
fread(buf, len, 1, fp);
//printf("%s\n", buf);
XMLDocument doc1;
doc1.Parse(buf);
free(buf);
doc1.Print();
cout<<"--------------------------"<<endl;
cout<<"get xml declaration"<<endl;
cout<<"--------------------------"<<endl;
XMLNode *decl = doc1.FirstChild();
XMLDeclaration *declaration = decl->ToDeclaration();
cout<<declaration->Value()<<endl;
cout<<"--------------------------"<<endl;
cout<<"add xml element"<<endl;
cout<<"--------------------------"<<endl;
XMLElement *root = doc1.RootElement();
XMLElement *userNode = doc1.NewElement("user");
userNode->SetAttribute("name", "ccc");
userNode->SetAttribute("age", "11");
root->InsertEndChild(userNode);
userNode = doc1.NewElement("user");
userNode->SetAttribute("name", "xiaoming");
userNode->SetAttribute("age", "22");
XMLElement *descNode = doc1.NewElement("description");
XMLText *descText = doc1.NewText("xiaoming is a good boy");
descNode->InsertEndChild(descText);
userNode->InsertEndChild(descNode);
root->InsertEndChild(userNode);
doc1.Print();
cout<<"--------------------------"<<endl;
cout<<"find xml element"<<endl;
cout<<"--------------------------"<<endl;
XMLElement *userNode1 = root->FirstChildElement("user");
while (userNode1 != NULL) {
const char *name = userNode1->Attribute("name");
cout<<name<<endl;
if (strcmp(name, "xiaoming") == 0) {
XMLElement *descNode1 = userNode1->FirstChildElement("description");
cout<<descNode1->GetText()<<endl;
}
userNode1 = userNode1->NextSiblingElement();
}
cout<<"--------------------------"<<endl;
cout<<"save xml element to file"<<endl;
cout<<"--------------------------"<<endl;
doc1.SaveFile("user1.xml");
cout<<"save ok"<<endl;

return 0;
}

因为这个例子是一点点写成的,每修改一点就调用g++编译还比较费劲,就写了个makefile

1
2
test1: test1.cpp tinyxml2.cpp
g++ -o $@ $^

这是执行测试程序后生出来的user1.xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<users>
<user name="aaa" age="33"/>
<user name="bbb" age="22"/>
<user name="ccc" age="11"/>
<user name="xiaoming" age="22">
<description>xiaoming is a good boy</description>
</user>
</users>