参考:
TinyXML使用方法[通俗易懂]
https://cloud.tencent.com/developer/article/2037579
TinyXML2 入门教程(这篇写很好,本文侧重讲解使用不过做多介绍)
不了解xml的建议自行查阅,在此不赘述。
开源库github链接:https://github.com/leethomason/tinyxml2
使用git直接拉取还是下载zip包都可
tinyxml2相比tinyxml进行了简化,只需要一个.h和一个.cpp即可使用,我下载的zip,解压完成后将tinyxml2.h和tinyxml2.cpp复制进自己的项目中即可。
在使用的地方包含头文件和命名空间
创建一个空的xml文件:
插入节点:
查询节点:
修改节点内容:
删除指定节点,获取xml文件申明:
代码如下:
// TinyXmlUsing.cpp : Defines the entry point for the console application.
//
#include "tinyxml2.h"
#include <iostream>
#include <stdio.h>
#include <string>
using namespace tinyxml2;
using namespace std;
//用户类
struct User {
public:
User() {
gender = 0;
};
User(const string& userName, const string& password, int gender, const string& mobile, const string& email) {
this->userName = userName;
this->password = password;
this->gender = gender;
this->mobile = mobile;
this->email = email;
};
string userName;
string password;
int gender;
string mobile;
string email;
};
//function:根据用户名获取用户节点
//param:root:xml文件根节点;userName:用户名
//return:用户节点
XMLElement* queryUserNodeByName(XMLElement* root, const string& userName) {
XMLElement* userNode = root->FirstChildElement("User");
while (userNode != NULL) {
if (userNode->Attribute("Name") == userName)
break;
userNode = userNode->NextSiblingElement();//下一个兄弟节点
}
return userNode;
}
// 结合queryUserNodeByName使用返回节点所有信息
User* queryUserByName(const char* xmlPath, const string& userName) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != 0) {
cout << "load xml file failed" << endl;
return NULL;
}
XMLElement* root = doc.RootElement();
XMLElement* userNode = queryUserNodeByName(root, userName);
if (userNode != NULL) { //searched successfully
User* user = new User();
user->userName = userName;
user->password = userNode->Attribute("Password");
XMLElement* genderNode = userNode->FirstChildElement("Gender");
user->gender = atoi(genderNode->GetText());
XMLElement* mobileNode = userNode->FirstChildElement("Mobile");
user->mobile = mobileNode->GetText();
XMLElement* emailNode = userNode->FirstChildElement("Email");
user->email = emailNode->GetText();
return user;
}
return NULL;
}
//function:修改指定节点内容 也依赖queryUserNodeByName函数
//param:xmlPath:xml文件路径;user:用户对象
//return:bool
bool updateUser(const char* xmlPath, User* user) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != 0) {
cout << "load xml file failed" << endl;
return false;
}
XMLElement* root = doc.RootElement();
XMLElement* userNode = queryUserNodeByName(root, user->userName);
if (userNode != NULL) {
if (user->password != userNode->Attribute("Password")) {
userNode->SetAttribute("Password", user->password.c_str()); //修改属性
}
XMLElement* genderNode = userNode->FirstChildElement("Gender");
if (user->gender != atoi(genderNode->GetText())) {
char * gender_char = new char[8];
sprintf(gender_char, "%d", user->gender);
genderNode->SetText(gender_char); //修改节点内容
}
XMLElement* mobileNode = userNode->FirstChildElement("Mobile");
if (user->mobile != mobileNode->GetText()) {
mobileNode->SetText(user->mobile.c_str());
}
XMLElement* emailNode = userNode->FirstChildElement("Email");
if (user->email != emailNode->GetText()) {
emailNode->SetText(user->email.c_str());
}
if (doc.SaveFile(xmlPath) == 0)
return true;
}
return false;
}
//function:insert XML node 增加XML文件的节点 根据需求灵活修改
//param:xmlPath xml 文件路径; user 用户对象
//return:0 成功; 非 0 失败
int insertXMLNode(const char* xmlPath, const User& user) {
XMLDocument doc;
int res = doc.LoadFile(xmlPath); // 加载xml文件
if (res != 0)
{
//cout << "load xml file failed" << endl;
cout << "加载xml文件失败!" << endl;
return res;
}
XMLElement* root = doc.RootElement(); // 获取根节点
XMLElement* userNode = doc.NewElement("User"); // 创建user节点
userNode->SetAttribute("Name", user.userName.c_str()); // user节点下添加属性值
userNode->SetAttribute("Password", user.password.c_str()); // user节点下添加属性值
root->InsertEndChild(userNode); // 根节点下插入user节点
XMLElement* gender = doc.NewElement("Gender"); // 创建Gender节点
char * gender_char = new char[8];
// 将int转为char* 写入节点
sprintf(gender_char, "%d" , user.gender);
/* itoa的使用说明:
int 转为char* 需要包含头文件<cstdlib> 第三个参数用于将数字转换成不同的进制
还需要添加在预处理器添加_CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS
故不在此使用 感兴趣请自行查阅
*/
//itoa(user.gender, gender_char,10);
XMLText* genderText = doc.NewText(gender_char);
gender->InsertEndChild(genderText);
userNode->InsertEndChild(gender); // user节点下插入Gender节点
XMLElement* mobile = doc.NewElement("Mobile"); // 创建Mobile节点
mobile->InsertEndChild(doc.NewText(user.mobile.c_str()));
userNode->InsertEndChild(mobile); // user节点下插入Mobile节点
XMLElement* email = doc.NewElement("Email"); // 创建Email节点
email->InsertEndChild(doc.NewText(user.email.c_str()));
userNode->InsertEndChild(email); // user节点下插入Email节点
return doc.SaveFile(xmlPath);
}
//function:删除指定节点内容
//param:xmlPath:xml文件路径;userName:用户名称
//return:bool
bool deleteUserByName(const char* xmlPath, const string& userName) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != 0) {
cout << "load xml file failed" << endl;
return false;
}
XMLElement* root = doc.RootElement();
//doc.DeleteNode(root);//删除xml所有节点
XMLElement* userNode = queryUserNodeByName(root, userName);
if (userNode != NULL) {
userNode->DeleteAttribute("Password");//删除属性
XMLElement* emailNode = userNode->FirstChildElement("Email");
userNode->DeleteChild(emailNode); //删除指定节点
//userNode->DeleteChildren();//删除节点的所有孩子节点
if (doc.SaveFile(xmlPath) == 0)
return true;
}
return false;
}
//function:获取xml文件申明
//param:xmlPath:xml文件路径;strDecl:xml申明
//return:bool
bool getXMLDeclaration(const char* xmlPath, string& strDecl) {
XMLDocument doc;
if (doc.LoadFile(xmlPath) != 0) {
cout << "load xml file failed" << endl;
return false;
}
XMLNode* decl = doc.FirstChild();
if (NULL != decl) {
XMLDeclaration* declaration = decl->ToDeclaration();
if (NULL != declaration)
{
strDecl = declaration->Value();
return true;
}
}
return false;
}
//function:create a xml file 创建一个xml文件
//param:xmlPath:xml文件路径
//return:0,成功;非0,失败
int createXML(const char* xmlPath) {
const char* declaration = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
XMLDocument doc;
doc.Parse(declaration);//会覆盖xml所有内容
//修改or添加申明可以使用如下两行XMLDeclaration 相当于修改第一层节点
//!切记不要和Parse一起使用 否则会添加两个申明
//XMLDeclaration* new_dec = doc.NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\" addshenming = \"shenming\" ");
//doc.InsertFirstChild(new_dec);
XMLElement* root = doc.NewElement("DBUSER"); // 创建根节点
doc.InsertEndChild(root);
return doc.SaveFile(xmlPath);
}
int main()
{
// 创建一个空的xml文件
int flag = createXML("qtreetestxml.xml");
//std::cout << flag;
User oneUser;
oneUser.userName = "张三";
oneUser.password = "1";
oneUser.gender = 0;
oneUser.mobile = "110";
oneUser.email = "1@qq.com";
// 插入节点
insertXMLNode("qtreetestxml.xml",oneUser);
// 查询节点
User* query_data = queryUserByName("qtreetestxml.xml", "张三");
cout << query_data->userName <<":"<< query_data->mobile<<endl;
// 修改节点内容 根据用户名字进行查找修改的所以名字得一样 可根据需求自由修改
User oneUser1;
oneUser1.userName = "张三";
oneUser1.password = "7";
oneUser1.gender = 1;
oneUser1.mobile = "119";
oneUser1.email = "1177@qq.com";
bool updata_flag = updateUser("qtreetestxml.xml", &oneUser1);
// 删除指定节点
bool del_flage = deleteUserByName("qtreetestxml.xml", "张三");
// 获取xml文件申明
string strDecl;
getXMLDeclaration("qtreetestxml.xml", strDecl);
cout << strDecl << endl;
system("pause");
return 0;
}