TinyXML2使用教程

TinyXML2使用教程TinyXML2使用教程原文转自http://blog.csdn.net/K346K346/article/details/487504171.TinyXML2概述TinyXML2是simple、small、efficient开源的C++XML文件解析库,可以很方便的应用到现有的项目之中。非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。TinyXML2详细介绍与源码获取方法详见:TinyXML2官网。2.TinyXML1与TinyXML2对比TinyXML1与TinyXM

大家好,又见面了,我是你们的朋友全栈君。

TinyXML2使用教程

原文转自 http://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。

使用场景:存储用户信息。

用户数据表设计如下:
在这里插入图片描述

对应XML文件实现如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DBUSER>
    <User Name=”lvlv” Password =123456>
    <Gender></Gender>
    <Mobile ></ Mobile>
    <Email ></ Email >
</User>

从中可以看出,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;
    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>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;
    else
        cout<<"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();
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/142022.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • prometheus 表达式

    prometheus 表达式avg_over_time(my_inprogress_requests{job=”mhc”}[5m]offset3m)返回time=1550664637开始向前偏移3分钟之前的五分钟的平均值curl-XGET\’http://mhc-linux:9090/api/v1/query?query=avg_over_time%28my_inprogress_requests{jo…

    2022年10月25日
  • Netty In Action中国版 – 第二章:第一Netty程序

    Netty In Action中国版 – 第二章:第一Netty程序

  • 玩守望先锋显示渲染器丢失_win10守望先锋渲染内存不足

    玩守望先锋显示渲染器丢失_win10守望先锋渲染内存不足解决游玩守望先锋时出现"渲染设备已丢失"笔者配置:cpu:amd3600显卡:rtx2060出现问题:在打守望先锋的时候出现"渲染设备丢失。。。。&quot

  • 归并排序算法详细图解_归并排序算法详解

    归并排序算法详细图解_归并排序算法详解一、什么是归并排序1.概念归并排序(Mergesort)是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的2.算法原理这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照归并排序的思想,我们要把序列逐层进行拆分序列逐层拆分如下然后从下往上逐层合并,首先对第一层序列1(只包含元素4)和序列2(只包含元素5)进行合并创建一个大序列,序列长度为两个小序列长度

    2022年10月20日
  • 卷积与转置卷积

    卷积与转置卷积当正向卷积步长不为1时(常常可能为2),转置卷积步长为: 转置卷积填充由正向卷积的卷积核和填充决定:  转置卷积的核和正向卷积一样:转置卷积的输出公式:     转置卷积又称微步卷积(“微步”的含义指:新的步长为1,而之前的步长为2,使得转置卷积的滑窗处理相比较卷积的“小”。),可以视作传统卷积操作的一种“逆向”传递过程;并且,转置卷积受“正向”卷积的参数约束,即步长stride和零填充…

  • ajax 长轮询_js 轮询

    ajax 长轮询_js 轮询1.三者介绍【1】http协议介绍1)介绍:http协议是请求/响应范式的,每个http响应都对应一个http请求,http协议是无状态的,多个http请求之间是没有关系的;2)http协议的被动性:在标准的HTTP请求响应语义中,浏览器发起请求,服务器发送一个响应,这意味着在浏览器发起新请求前,服务器不能发送新信息给客户端浏览器;【2】htt

    2022年10月14日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号