安装
TinyXml2 Git 源码下载地址:https://github.com/leethomason/tinyxml2
步骤1:首先,你需要下载tinyxml2的源代码。你可以从Github或者源代码官方网站下载。并上传至/usr/local/source_code/
步骤2:下载完成后,需要将源代码解压,可以使用以下命令:
tar -zxvf tinyxml2-8.1.0.tar.gz
步骤3:解压后,切换到源代码目录:
cd tinyxml2-8.1.0
步骤4:执行make && make install 命令进行安装:
make && make install
温馨提示:完成以上步骤后,在/usr/local/lib下会生成libtinyxml2.so动态库和/usr/local/include下生成tinyxml2.h头文件。你可以使用以下命令查看是否安装成功:
ls /usr/local/lib | grep tinyxml2
ls /usr/local/include | grep tinyxml2
如果看到libtinyxml2.so和tinyxml2.h,则说明成功安装了tinyxml库。
TinyXml2 库
简介
TinyXML2 是简单实用的开源的 C++XML 文件解析库,可以很方便的应用到现有的项 目之中。 TinyXML2 解析器相对 TinyXML1 在代码上是完全重写,使其更适合于游戏开发 中使用。它使用更少的内存,更快,并使用更少的内存分配。
由于 XML 的树状结构,TinyXML2 将 XML 的节点抽象为 XMLNode,XML 中除了把属 性 key-value 抽象为 XMLAttribute 类型外,其余的都看作 XMLNode 的子类,首先将整个 XML 文档抽象为 XMLDocument,将声明部分抽象为 XMLDeclaration,将注释抽象为 XMLComment,将元素抽象为 XMLElement,将文本抽象为 XMLText。
核心:节点、元素、属性和值
XMLAttribute 是解析 XML 的属性的类,XML 中的属性都与 XML 的 Element 绑定,并且为 key-value 类型。
XMLComment 主要是处理 XML 注释的类,注释的存储形式为""。
XMLDeclaration 主要是处理 XML 中声明的类,声明的存储形式为"<? declaration ?>"。 XMLDocument 代表 XML 整个实体,TinyXML2 中只有 XMLDocument 类可以被实例化,其他的类必
须通过 XMLDocument 提供的 new 方法进行实例化,而不能直接实例化。XMLNode
的其他实体类把构造函数定义为 protected,不能被外部实例化,这样保证使用 XMLDocument 进行内存的管理,避免产生内存泄漏的风险。
XMLElement XMLElement 类是 XMLNode 中最重要的一个类,其存储方式有<foo/>和<foo></foo> 两 种 形 式 , 它 包 含 了 一 个 XMLAttribute 的 根 指 针 , 这 个 root 指 针 指 向 XMLAttribute 的第一个属性键值对。
XMLHandle 主要用来访问元素。
XMLNode 是几乎 XML 所有元素(XMLAttribute 除外)的基类,XML 本质是一种树形结构,而 整个 XML 就是由许多的节点(XMLNode)组成,在 TinyXML2 中每个 XMLNode 节点都 保存了父亲、前驱、后继、孩子头节点和孩子尾节点信息,便于查询、插入、检 索。
XMLPrinter 是 XMLVisitor 类的子类,主要实现的写 XML 的功能,其提供了两种书写方式,一 是构建 XMLDocument,二是直接 push 字段。
XMLText 主要是处理 XML 文本的类,文本信息又分为 CDATA 和普通文本。CDATA 是有专属的 开始字符"<![CDATA[",而普通的文本存储形式如">text<"。
XMLUnknown 存储形式为"<! unknown>"。
XMLVisitor 访问者模式的基类,它主要定义了访问者的接口,而在 XMLNode 的子类的 accept 方法中调用这些方法来完成对自身的访问。
示例代码
前提条件:在/usr/local/source_code 创建目录:tinyxml_demmo,并创建tinyXmlDemo.cpp文件,文件内容如下:
#include <iostream>
#include "tinyxml2.h"
#include <stdio.h>
#include <stdlib.h>
using namespace tinyxml2;
/*
enum XMLError {
XML_SUCCESS = 0,
XML_NO_ATTRIBUTE,
XML_WRONG_ATTRIBUTE_TYPE,
XML_ERROR_FILE_NOT_FOUND,
XML_ERROR_FILE_COULD_NOT_BE_OPENED,
XML_ERROR_FILE_READ_ERROR,
XML_ERROR_PARSING_ELEMENT,
XML_ERROR_PARSING_ATTRIBUTE,
XML_ERROR_PARSING_TEXT,
XML_ERROR_PARSING_CDATA,
XML_ERROR_PARSING_COMMENT,
XML_ERROR_PARSING_DECLARATION,
XML_ERROR_PARSING_UNKNOWN,
XML_ERROR_EMPTY_DOCUMENT,
XML_ERROR_MISMATCHED_ELEMENT,
XML_ERROR_PARSING,
XML_CAN_NOT_CONVERT_TEXT,
XML_NO_TEXT_NODE,
XML_ELEMENT_DEPTH_EXCEEDED,
XML_ERROR_COUNT
};
*/
//创建XML文件
int createXML(const char* xmlPath)
{
XMLDocument doc;
if (XML_ERROR_FILE_NOT_FOUND != doc.LoadFile(xmlPath)) {
std::cout << "file has been existed !" << std::endl;
return 0;
}
//添加声明 <?xml version="1.0" encoding="UTF-8" ?>
XMLDeclaration *declaration = doc.NewDeclaration();
doc.InsertFirstChild(declaration);
XMLElement *root = doc.NewElement("Users");
doc.InsertEndChild(root);
XMLElement *userNode = doc.NewElement("User");
//添加属性
userNode->SetAttribute("Name", "milo");
userNode->SetAttribute("Password", "pwd");
root->InsertEndChild(userNode);
return doc.SaveFile(xmlPath);
}
void loadXML(const char* xmlPath) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
std::cout << "load xlm file failed" << std::endl;
return;
}
XMLPrinter printer;
doc.Print( &printer);
std::cout << printer.CStr();
}
//添加性别,号码,邮箱 再添加一个用户
int addXML1(const char* xmlPath) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
std::cout << "load xlm file failed" << std::endl;
return -1;
}
XMLElement *root = doc.RootElement();
XMLElement *userNode = root->FirstChildElement("User");
XMLElement *gender = doc.NewElement("Gender");
XMLText* genderText = doc.NewText("man");
gender->InsertFirstChild(genderText);
userNode->InsertFirstChild(gender);
XMLElement *mobile = doc.NewElement("Mobile");
mobile->InsertFirstChild(doc.NewText("186****3143"));
userNode->InsertEndChild(mobile);
XMLElement *email = doc.NewElement("Email");
email->InsertFirstChild(doc.NewText("472251823@qq.com"));
userNode->InsertEndChild(email);
XMLElement *userNode2 = doc.NewElement("User");
userNode2->SetAttribute("Name", "king");
userNode2->SetAttribute("Password", "pwd2");
root->InsertEndChild(userNode2);
XMLElement *mobile2 = doc.NewElement("Mobile");
mobile2->InsertFirstChild(doc.NewText("186****3143"));
userNode2->InsertEndChild(mobile2);
return doc.SaveFile(xmlPath);
}
//在性别后面添加年龄,再添加一个号码
int addXML2(const char* xmlPath)
{
XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS)
{
std::cout<<"load xml file failed"<<std::endl;
return false;
}
XMLElement* root=doc.RootElement();
XMLElement* userNode=root->FirstChildElement("User");
XMLElement* gender = userNode->FirstChildElement("Gender");
XMLElement* age = doc.NewElement("Age");
age->InsertFirstChild(doc.NewText("18"));
userNode->InsertAfterChild(gender,age);
XMLElement* mobile = userNode->FirstChildElement("Mobile");
mobile->SetAttribute("Location","home");
XMLElement* mobile1 = doc.NewElement("Mobile");
mobile1->SetAttribute("Location","company");
mobile1->InsertFirstChild(doc.NewText("186****3143"));
userNode->InsertAfterChild(mobile, mobile1);
return doc.SaveFile(xmlPath);
}
//删除第一个号码,删除第二个号码的属性
int deleteXML(const char* xmlPath) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
std::cout << "load xlm file failed" << std::endl;
return -1;
}
XMLElement *root = doc.RootElement();
XMLElement *userNode = root->FirstChildElement("User");
XMLElement *mobile = userNode->FirstChildElement("Mobile");
userNode->DeleteChild(mobile);
XMLElement *mobile2 = userNode->FirstChildElement("Mobile");
mobile2->DeleteAttribute("Location");
return doc.SaveFile(xmlPath);
}
//将milo的年龄改为10000岁,将king的号码改为8888结尾
int updateXML(const char* xmlPath) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != XML_SUCCESS) {
std::cout << "load xlm file failed" << std::endl;
return -1;
}
XMLElement *root = doc.RootElement();
XMLElement *userNode = root->FirstChildElement("User");
while (userNode != NULL) {
if (0 == strncmp("milo", (userNode->Attribute("Name")), 11)) {
userNode->FirstChildElement("Age")->SetText("10000");
userNode = userNode->NextSiblingElement();
} else if (0 == strncmp("king", (userNode->Attribute("Name")), 11)) {
userNode->FirstChildElement("Mobile")->SetText("186****8888");
userNode = userNode->NextSiblingElement();
} else {
userNode = userNode->NextSiblingElement();
}
}
return doc.SaveFile(xmlPath);
}
//将milo的信息打印出来
int selectXML(const char* xmlPath)
{
XMLDocument doc;
if(doc.LoadFile(xmlPath)!=XML_SUCCESS)
{
std::cout<<"load xml file failed"<<std::endl;
return false;
}
XMLElement* root=doc.RootElement();
XMLElement* userNode=root->FirstChildElement("User");
while(userNode != NULL)
{
if( 0 == strncmp("milo",(userNode->Attribute("Name")),11))
{
std::cout << userNode->Attribute("Name") << std::endl;
std::cout << userNode->Attribute("Password") << std::endl;
std::cout << userNode->FirstChildElement("Age")->GetText() << std::endl;
std::cout << userNode->FirstChildElement("Gender")->GetText() << std::endl;
std::cout << userNode->FirstChildElement("Mobile")->GetText() << std::endl;
std::cout << userNode->FirstChildElement("Email")->GetText() << std::endl;
userNode = userNode->NextSiblingElement();
} else {
userNode = userNode->NextSiblingElement();
}
}
return 0;
}
int main( int argc, const char ** argv )
{
char xmlPath[] = "./0voice.xml";
/*创建*/
createXML(xmlPath);
loadXML(xmlPath);
printf("------------------------------\n");
/*增*/
addXML1(xmlPath);
loadXML(xmlPath);
printf("------------------------------\n");
addXML2(xmlPath);
loadXML(xmlPath);
printf("------------------------------\n");
/*删*/
deleteXML(xmlPath);
loadXML(xmlPath);
printf("------------------------------\n");
/*改*/
updateXML(xmlPath);
loadXML(xmlPath);
printf("------------------------------\n");
/*查*/
selectXML(xmlPath);
return 0;
}
源码编译,执行如下指令:
g++ tinyXmlDemo.cpp -o tinyXmlDemo -L/usr/local/lib/ -ltinyxml2
执行效果截图:
[root@localhost tinyxml_demmo]# g++ tinyXmlDemo.cpp -o tinyXmlDemo -L/usr/local/lib/ -ltinyxml2
[root@localhost tinyxml_demmo]# ll
总用量 120
-rw-r--r--. 1 root root 168 10月 23 15:36 parseXml.xml
-rwxr-xr-x. 1 root root 110536 10月 23 15:48 tinyXmlDemo
-rw-r--r--. 1 root root 7091 10月 23 15:47 tinyXmlDemo.cpp
[root@localhost tinyxml_demmo]# ./tinyXmlDemo
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User Name="milo" Password="pwd"/>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User Name="milo" Password="pwd">
<Gender>man</Gender>
<Mobile>186****3143</Mobile>
<Email>472251823@qq.com</Email>
</User>
<User Name="king" Password="pwd2">
<Mobile>186****3143</Mobile>
</User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User Name="milo" Password="pwd">
<Gender>man</Gender>
<Age>18</Age>
<Mobile Location="home">186****3143</Mobile>
<Mobile Location="company">186****3143</Mobile>
<Email>472251823@qq.com</Email>
</User>
<User Name="king" Password="pwd2">
<Mobile>186****3143</Mobile>
</User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User Name="milo" Password="pwd">
<Gender>man</Gender>
<Age>18</Age>
<Mobile>186****3143</Mobile>
<Email>472251823@qq.com</Email>
</User>
<User Name="king" Password="pwd2">
<Mobile>186****3143</Mobile>
</User>
</Users>
------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<Users>
<User Name="milo" Password="pwd">
<Gender>man</Gender>
<Age>10000</Age>
<Mobile>186****3143</Mobile>
<Email>472251823@qq.com</Email>
</User>
<User Name="king" Password="pwd2">
<Mobile>186****8888</Mobile>
</User>
</Users>
------------------------------
milo
pwd
10000
man
186****3143
472251823@qq.com