原文见 https://blog.csdn.net/K346K346/article/details/48750417

1.TinyXML2概述

TinyXML2是simple、small、efficient开源的C++ XML文件解析库,可以很方便的应用到现有的项目之中。非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。

TinyXML2详细介绍与源码获取方法详见:TinyXML2官网。


2. TinyXML1与TinyXML2对比

TinyXML1与TinyXML2这两个著名的开源XML文件解析库均出自Lee Thomason之手,向这位满怀开源精神的大家致敬。

TinyXML2适用于大部分的C/C++项目开发,经得住考验,是最好的选择。较TinyXML1而言,TinyXML2化繁为简,使用时只需要包含两个文件,而TinyXML1需要6个文件,一般生成静态链接库供项目的使用。TinyXML1详细介绍与源码见:TinyXML1官网。TinyXML1用法用例可以参考博文:TinyXML快速入门。

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 用户名 Vchar 3-20 Y Y
Password 密码 Char 32 Y N
Gender 性别 Int 1 N N
Mobile 电话 Char 11 N N
Email 电子邮箱 Varchar 1-50 N 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下载,见:TinyXML2。

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(itoa(user.gender));gender->InsertEndChild(genderText);userNode->InsertEndChild(gender);XMLElement* mobile = doc.NewElement("Mobile");mobile->InsertEndChild(doc.NewText(user.mobile.c_str()));userNode->InsertEndChild(mobile);XMLElement* email = doc.NewElement("Email");email->InsertEndChild(doc.NewText(user.email.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>15813354926</Mobile><Email>1589276509@qq.com</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,"13995648666","1586666@qq.com");if(updateUser("./user.xml",&user))cout<<"update successfully"<<endl;elsecout<<"update failed"<<endl;return 0;
}

修改结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER><User Name="lvlv" Password="00001111"><Gender>0</Gender><Mobile>13995648666</Mobile><Email>1586666@qq.com</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[])
{//删除用户某些信息if(deleteUserByName("./user.xml","lvlv"))cout<<"delete successfully"<<endl;elsecout<<"delete failed"<<endl;return 0;
}

删除结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER><User Name="lvlv"><Gender>10</Gender><Mobile>13995648666</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("./user.xml",strDecl)){cout<<"declaration:"<<strDecl<<endl;}return 0;
}

验证结果:

declaration:xml version="1.0" encoding="UTF-8" standalone="no"

4.2打印xml文件至标准输出

//function:将xml文件内容输出到标准输出
//param:xmlPath:xml文件路径
void print(const char* xmlPath)
{XMLDocument doc;if(doc.LoadFile("./user.xml")!=0){cout<<"load xml file failed"<<endl;return;}doc.Print();
}

4.3 xml文件内容输出至内存

XMLPrinter printer;
doc.Print( &printer );
// printer.CStr() has a const char* to the XML

4.4如何解析xml格式的字符串信息,不是文件中的

采用tinyXML中的TiXmlDocument类的Parse方法即可。例如:
const char * xmlString = "<?xml version=\"1.0\" standalone=no>\n<!– Our to do list data –>\n<ToDo>\n<Item priority=\"1\"> <bold>Toy store!</bold>\n</Item>\n<Item priority=\"2\"> Do bills</Item>\n</ToDo> ";
XMLDocument *doc = new XMLDocument();
doc->Parse(xmlString);
 
XMLElement * rootElement = doc->RootElement();
const char * rootName = rootElement->Value();

【转载】TinyXML2使用教程相关推荐

  1. TinyXML2使用教程

    TinyXML2使用教程 原文转自 http://blog.csdn.net/K346K346/article/details/48750417 1.TinyXML2概述 TinyXML2是simpl ...

  2. 【转】TinyXML2 入门教程

    转自:TinyXML2 入门教程_恋喵大鲤鱼的博客-CSDN博客_tinyxml2中文指南 代码编译运行环境:Linux 64bits + Debug + g++ -m64(-m 表示生成 64bit ...

  3. [转载]批处理入门教程

    [转载]批处理入门教程 写这篇教程的目的,是让每一个看过这些文字的朋友记住一句话:如果爱可以让事情变的更简单,那么就让它简单吧!看这篇教程的方法 脚本之家补充说明:批处理相对来说是比较简单的语言,大家 ...

  4. [转载]windbg简明教程

    [转载]windbg简明教程 文章作者:Sucsor on 2006.06.11 Windbg是 Microsoft公 司免费调试器调试集合中的GUI的调试器,支持Source和Assembly两种模 ...

  5. [转载]VBS入门教程 VBS基础教程

    [转载]VBS入门教程 VBS基础教程(收藏) VBS基础教程 VBS(VBScript的进一步简写)是基于Visual Basic的脚本语言. Microsoft Visual Basic是微软公司 ...

  6. 转载 树莓派vnc 教程

    VNC远程连接树莓派完全教程 爱上半导体 18-07-1712:48 树莓派3B.3B+自带了VNC,我们不需要在用指令给树莓派安装 为了能在电脑上使用VNC的方式远程树莓派,我真是操碎了心,断断续续 ...

  7. TinyXML2 入门教程

    代码编译运行环境:Linux 64bits + Debug + g++ -m64(-m 表示生成 64bits 的程序) 文章目录 1.TinyXML2 概述 2. TinyXML1 与 TinyXM ...

  8. [转载]SVN使用教程

    SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很多不同的版本,这就需要程序员有效的管理代码,在需要的时候可以迅速,准确取出相应的版本. Subversion是什么? ...

  9. 转载:ubuntu教程

    Ubuntu完全教程,让你成为Ubuntu高手! Ubuntu的发音 Ubuntu,源于非洲祖鲁人和科萨人的语言,发作 oo-boon-too 的音.了解发音是有意义的,您不是第一个为此困惑的人,当然 ...

最新文章

  1. 详解Silverlight Treeview的HierarchicalDataTemplate使用
  2. Flash与jsp通信类封装
  3. android性能测试工具之dumpsys
  4. Python笔记(1) Python简介
  5. Java多线程学习(八)线程池与Executor 框架
  6. Python中字符串格式化输出的学习笔记
  7. Bootstrap 列偏移\列嵌套\列排序
  8. AjaxControltoolkit学习笔记—ListSearch 使用详解
  9. python-sklearn数据分析-线性回归和支持向量机(SVM)回归预测(实战)
  10. 利用云服务器自动发送天气预报邮件
  11. H5页面投票怎么制作
  12. ESP32开发1---ESP32环境搭建(ESP-IDF+VSCode)
  13. python 网格交易源码_Python版简单网格策略
  14. 【环境配置】反向SSH——家中电脑连接校园内网服务器
  15. 微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
  16. kotlin协程与线程池
  17. python起笔落笔__怎样在python里让海龟画图抬笔落笔?
  18. 4.5 银行间拆借利率爬取(switch_to.frame()函数切换到子网页,浏览器同级页面切换--switch.window()函数)
  19. OpenCV-Python之模板匹配
  20. php f4v元数据,[AS3]视频播放器处理flv,mp4,f4v元数据的问题

热门文章

  1. 《剑指0ffer》刷题笔记 -01 二维数组中的查找
  2. 利用阿里云实现异地容灾的解决方案
  3. php vox转码,Audio Track Convert Tool(音轨转码工具)
  4. 使用jsp实现用户注册及登录
  5. Git Bash/GUI Here “找不到应用程序问题” 的解决方案
  6. godot 外部编辑器配置
  7. 职业综合英语 章节答案考试答案 深圳职业技术学院[渝粤教育]
  8. Android 11 正式版发布
  9. php中调整图片大小,php 调整图片尺寸的简单示例
  10. CLIP改进工作串讲(上)