TinyXML2使⽤教程(转)
原⽂转⾃
1.TinyXML2概述
TinyXML2是simple、small、efficient开源的C++ XML⽂件解析库,可以很⽅便的应⽤到现有的项⽬之中。⾮常适合存储简单数据,配置⽂件,对象序列化等数据量不是很⼤的操作。
TinyXML2详细介绍与源码获取⽅法详见:。
2. TinyXML1与TinyXML2对⽐
TinyXML1与TinyXML2这两个著名的开源XML⽂件解析库均出⾃Lee Thomason之⼿,向这位满怀开源精神的⼤家致敬。
TinyXML2适⽤于⼤部分的C/C++项⽬开发,经得住考验,是最好的选择。较TinyXML1⽽⾔,TinyXML2化繁为简,使⽤时只需要包含两个⽂件,⽽TinyXML1需要6个⽂件,⼀般⽣成静态链接库供项⽬的使⽤。TinyXML1详细介绍与源码见:。TinyXML1⽤法⽤例可以参考博⽂:。
TinyXML2使⽤了与TinyXML1相似都可API,并且拥有丰富的案例。但TinyXML2解析器相对TinyXML1在代码上是完全重写,使其更适合于游戏开发中使⽤。它使⽤更少的内存,更快,并使⽤更少的内存分配。
TinyXML2⽆需STL,也放弃了对STL⽀持。所有字符串查询均使⽤C风格字符串“const char *”来表⽰,省去string类型对象的构造,并使代码更简单。
⼆者共同点:(1)都使⽤了简单易⽤的API。(2)都是基于DOM(Document Object Model,⽂档对象模型)的解析器。(3)都⽀持UTF-8编码。
TinyXML2的优点:(1)对⼤部分⼤部分的C/C++项⽬具有普适性。(2)使⽤较少的内存(约TinyXML1的40%),速度变得更快。(3)没有C++的STL的要求。(4)更接近现代C++的特性,如使⽤了适当的命名空间。(5)适当有效的处理了的空⽩字符(空格,TAB 和回车)。
TinyXML1的优点:(1)可以报告分析错误的位置。(2)提供⼀些C++ STL公约⽀持:流和字符串。(3)拥有⾮常成熟和良好的调试代码库。
3. TinyXML2的⽤法⽤例
TinyXML2的⽹上教程并不多见,醍醐灌顶,受益匪浅的教程更是凤⽑麟⾓。有的也是蜻蜓点⽔、参差
不齐的泛泛⽽谈。最终,所能参考的资料也就是官⽹的⽂档和⽰例代码,但却有点晦涩难懂。因此,本⽂就为了解决这个尴尬的局⾯,结合官⽹的资料和⽹上资源,尽量详细的列出TinyXML2的常见⽤法⽤例,不⾜之处,请留⾔补充,后续增加修改。
xml⽂件本质就是⼩型的,换个⾓度来说就是,对数据库有什么操作,那么对xml⽂件就应能实现什么操作。⼀般⽽⾔,对数据库的操作包括以下⼏种:新建数据库和对数据库增删查改。那么对应xml⽂件就是新建xml⽂件、增加xml⽂件的节点,删除xml⽂件的指定节点,查询xml ⽂件指定节点的值,修改xml⽂件中节点的值。
使⽤⽅法:将tinyxml2.cpp和tinyxml2.h拷贝⾄项⽬⽬录,使⽤时包含#include “tinyxml2.h”和using namespace tinyxml2。
使⽤场景:存储⽤户信息。
⽤户数据表设计如下:
变量名描述类型长度(字节)不为空主键
UserName⽤户名Vchar3-20Y Y
Password密码Char32Y N
Gender性别Int1N N
Mobile电话Char11N N
Email电⼦邮箱Varchar1-50N N
对应XML⽂件实现如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
<User Name=”lvlv” Password =”123456”>
<Gender></Gender>
<Mobile ></ Mobile>
<Email ></ Email >
</User>
.
.
.
<DBUSER>
从中可以看出,XML由三⼤部分组成,分别是声明、根节点和其它节点。其中xml⽂件的声明包括三⽅⾯的内容:Version、Standalone和Encoding。下⾯将详细列出常见tinyxml2的⽤法。
注意:以下⽰例代码针对本⼈下载使⽤的TinyXML2,官⽹的TinyXML2在不断的完善和更新当中,最新的TinyXML2和本⼈的⽰例代码可能会有出⼊。本⼈使⽤的TinyXML2是2015.9.23从官⽹下载的,已上传⾄CSDN下载,见:。
3.1创建XML⽂件
⽰例代码:
//function:create a xml file
//param:xmlPath:xml⽂件路径
//return:0,成功,⾮0,失败
int createXML(const char* xmlPath)
{
const char* declaration ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
XMLDocument doc;
doc.Parse(declaration);//会覆盖xml所有内容
//添加申明可以使⽤如下两⾏
//XMLDeclaration* declaration=doc.NewDeclaration();
//doc.InsertFirstChild(declaration);
XMLElement* root=doc.NewElement("DBUSER");
doc.InsertEndChild(root);
return doc.SaveFile(xmlPath);
}
创建结果:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER/>
3.2增加xml⽂件的节点
⽰例代码:
//⽤户类
class 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:insert XML node
//param:xmlPath:xml⽂件路径; user:⽤户对象
//return:0:成功; ⾮0:失败
int insertXMLNode(const char* xmlPath,const User& user)
{
XMLDocument doc;
int res=doc.LoadFile(xmlPath);
if(res!=0)
{
cout<<"load xml file failed"<<endl;
return res;
}
XMLElement* root=doc.RootElement();
XMLElement* userNode = doc.NewElement("User");
userNode->SetAttribute("Name",user.userName.c_str());
userNode->SetAttribute("Password ",user.password.c_str());
root->InsertEndChild(userNode);
XMLElement* gender = doc.NewElement("Gender");
XMLText* genderText=doc.NewText(der));
gender->InsertEndChild(genderText);
userNode->InsertEndChild(gender);
XMLElement* mobile = doc.NewElement("Mobile");
mobile->InsertEndChild(doc.bile.c_str()));
userNode->InsertEndChild(mobile);
XMLElement* email = doc.NewElement("Email");
email->InsertEndChild(doc.ail.c_str()));
userNode->InsertEndChild(email);
return doc.SaveFile(xmlPath);
}
创建结果:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
<User Name="lvlv" Password ="12346">
<Gender>1</Gender>
<Mobile>158********</Mobile>
<Email>1589276509@qq</Email>
</User>
</DBUSER>
3.3查询xml⽂件的指定节点
Xml⽂件中,⼀个⽤户节点存储⼀个⽤户的信息。因此,对⽤户信息的增删查改,即⽆论查询节点、删除节点、修改节点和增加节点,都需要获取需要操作的节点。那么先实现⼀个根据⽤户名获取节点指针的函数:
//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;
}
在以上函数的基础上,获取⽤户信息的函数:
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;
3.4修改xml⽂件的指定节点
//function:修改指定节点内容
//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()))
{
genderNode->SetText(itoa(user->gender).c_str());  //修改节点内容
}
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;
}
验证代码:
int main(int argc,char* argv[])
{
//修改⽤户信息
User user("lvlv","00001111",0,"139********","1586666@qq");
if(updateUser("./l",&user))
cout<<"update successfully"<<endl;
else
cout<<"update failed"<<endl;
return 0;
}
修改结果:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
<User Name="lvlv" Password="00001111">
<Gender>0</Gender>
<Mobile>139********</Mobile>
<Email>1586666@qq</Email>
</User>
</DBUSER>
3.5删除xml⽂件的指定节点的信息
//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;
}
验证代码:
int main(int argc,char* argv[])
{游戏xml文件修改
//删除⽤户某些信息
if(deleteUserByName("./l","lvlv"))
cout<<"delete successfully"<<endl;
else
cout<<"delete failed"<<endl;
return 0;
}
删除结果:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
<User Name="lvlv">
<Gender>10</Gender>
<Mobile>139********</Mobile>
</User>
</DBUSER>
4.其它常见⽤例
4.1获取xml⽂件申明
/
/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;
}
验证代码:
int main(int argc,char* argv[])
{
//获取xml⽂件申明
string strDecl;
if(getXMLDeclaration("./l",strDecl))
{
cout<<"declaration:"<<strDecl<<endl;
}
return 0;
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。