TinyXml2是开源的c++xml文件解析库,简单实用,非常适合存储简单数据,配置文件,对象序列化等数据量不是很大的操作。

  (1)DOM

DOM(Document Object Model),即文档对象模型,是针对XML并经过扩展用于HTML的应用程序编程接口(API)。

DOM本质上是一种接口(API),是专门操作网页内容的API标准。DOM把整个页面映射为一个多层节点结构,HTML或XML页面中的每个组成部分都是某种类型的节点。借助DOM提供的API,开发人员可以删除、添加、替换或修改任何节点。

DOM标准被分为三个不同的部分:
.核心 DOM - 针对任何结构化文档的标准模型
.XML DOM - 针对 XML 文档的标准模型
.HTML DOM - 针对 HTML 文档的标准模型
文档--整个网页文档
对象--将网页中的每一个部分都转化为了一个对象
模型--使用模型来表示对象间的关系,这样方便我们获取对像

    (2)tinyxml2的简单示例

待读取的xml文档:

<?xml version="1.0"?>
<root>
<name>MenAngel</name>
</root>

xml文件名为test.xml,代码如下

编译命令 :g++ -g -std=c++11 -I /usr/include main.cpp /usr/include/tinyxml2/tinyxml2.cpp -o test

#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2; int main(int argv,char *argc[])
{
XMLDocument xmlDoc;
xmlDoc.LoadFile("test.xml");
int errorID = xmlDoc.ErrorID();
if(errorID)
{
cout<<"Load xml test.xml fail!"<<endl;
return -;
}
cout<<"Load xml test.xml success!"<<endl;
XMLElement *pRootElement = xmlDoc.RootElement();
const char * name = pRootElement->FirstChildElement("name")->GetText();
cout<<"name = "<<name<<endl;
return ;
}
Load xml test.xml success!
name = MenAngel

    (3)tinyxml2的详细使用范例

通常xml包含如下四个部分:

//节点构成xml的基本单元
文档节点; 对应 XMLDocument
元素节点; 对应 XMLElement
属性节点; 对应 XMLAttribute
文本节点; 对应 XMLText

    1.生成xml文档(增删改查)

#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2;
int createXML(const char * xmlPath)
{
XMLDocument doc;
if(XML_ERROR_FILE_NOT_FOUND != doc.LoadFile(xmlPath))
{
cout<<"file is exits!"<<endl;
return ;
}
//1.添加声明 方法一
//const char* declaration ="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
//doc.Parse(declaration);//会覆盖xml所有内容
//2.添加声明 方法二
//<?xml version="1.0" encoding="UTF-8"?>
XMLDeclaration *declaration = doc.NewDeclaration();
doc.InsertFirstChild(declaration);
//3.新建root根节点
XMLElement *root = doc.NewElement("root");
doc.InsertFirstChild(root);
doc.InsertEndChild(root);
//4.给root添加节点
XMLElement* userNode = doc.NewElement("person");
//4.1设置属性
userNode->SetAttribute("name","MenAngel");
userNode->SetAttribute("passwd",);
//4.2设置开始标签及文本值
userNode->InsertFirstChild(doc.NewText("sunjimeng"));
//4.3设置结束标签
root->InsertEndChild(userNode);
return doc.SaveFile(xmlPath);
}
int addXML(const char *xmlPath)
{
XMLDocument doc;
if( XML_SUCCESS != doc.LoadFile(xmlPath))
{
cout<<"load xml file failed"<<endl;
return -;
}
//再添加一个没有属性的name = MenAngel的 person节点
XMLElement *newPerson = doc.NewElement("person");
newPerson->InsertFirstChild(doc.NewText("MenAngel"));
XMLElement *root = doc.RootElement();
root->InsertEndChild(newPerson);
return doc.SaveFile(xmlPath);
}
int modifyXML(const char *xmlPath)
{
XMLDocument doc;
if( XML_SUCCESS != doc.LoadFile(xmlPath))
{
cout<<"load xml file failed"<<endl;
return -;
}
//1.获得根节点
XMLElement *root = doc.RootElement();
//2.获得根节点root指定名称的第一个子元素
//获得根节点第一个子元素 root->FirstChild();
XMLElement *newPerson = root->FirstChildElement("person");
newPerson->SetAttribute("name","user");
newPerson->SetText("MenAngel");
newPerson->DeleteAttribute("passwd");
//3.查询属性及值
cout<<"<person> name = "<<newPerson->Attribute("name")<<" value = "<<newPerson->GetText()<<endl;
newPerson = newPerson->NextSiblingElement();
root->DeleteChild(newPerson);
return doc.SaveFile(xmlPath);
}
int main(int argv,char *argc[])
{
const char * filename = "create.xml";
int iRet = createXML(filename);
if(iRet != XML_SUCCESS)
cout<<"create xml fail!"<<endl;
iRet = addXML(filename);
if(iRet != XML_SUCCESS)
cout<<"add xml fail!"<<endl;
iRet = modifyXML(filename);
if(iRet != XML_SUCCESS)
cout<<"modify or delte xml fail!"<<endl;
return iRet;
}
//命令行打印
<person> name = user value = MenAngel
//create.xml
<?xml version="1.0" encoding="UTF-8"?>
<root>
<person name="user">MenAngel</person>
</root>

    2.利用for和while循环遍历xml文档中所有文件(两层)

//test.xml
<?xml version="1.0"?>
<root>
<name>MenAngel</name>
<age></age>
<gender>boy</gender>
<hobbys type="array">
<value>语文</value>
<value>数学</value>
<value>英语</value>
</hobbys>
<scores type="array">
<value>
<course>语文</course>
<score></score>
</value>
<value>
<course>数学</course>
<score></score>
</value>
<value>
<course>英语</course>
<score></score>
</value>
</scores>
</root>
//main.cpp
#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2; int main(int argv,char *argc[])
{
XMLDocument doc;
if(XML_SUCCESS != doc.LoadFile("test.xml"))
{
cout<<"load xml file failed!"<<endl;
return -;
}
XMLElement *root = doc.RootElement();
XMLElement *ptrNode = root->FirstChildElement();
do
{ //hobbys标签、scores标签为array类型可以进入
if(ptrNode->Attribute("type") != NULL)
{
cout<<ptrNode->Name()<<" is "<<ptrNode->Attribute("type")<<endl;
//两种标签下均是 value子标签,可以for循环迭代
for(const XMLNode *tempNode = ptrNode->FirstChild();(tempNode != NULL && tempNode->FirstChildElement() == NULL);tempNode = tempNode->NextSibling())
{
cout<<"方法一:"<<tempNode->Value()<<":"<<tempNode->ToElement()->GetText()<<endl;
}
for(XMLElement *ptrElement = ptrNode->FirstChildElement("value");ptrElement; ptrElement=ptrElement->NextSiblingElement("value"))
//hobbys标签下没有子节点,直接是值
if(ptrElement->FirstChildElement() == NULL && ptrElement->GetText() != NULL)
cout<<"方法二:"<<ptrElement->Name()<<":"<<ptrElement->GetText()<<endl;
//scores标签下有两个子节点:course、scores
else
{
cout<<" "<<ptrElement->Value()<<":"<<endl
<<" "<<ptrElement->FirstChildElement("course")->Name()<<":"<<ptrElement->FirstChildElement("course")->GetText()<<endl
<<" "<<ptrElement->FirstChildElement("score")->Name()<<":"<<ptrElement->FirstChildElement("score")->GetText()<<endl;
}
ptrNode = ptrNode->NextSiblingElement();
continue;
}
cout<<ptrNode->Name()<<":"<<ptrNode->GetText()<<endl;
ptrNode = ptrNode->NextSiblingElement();
}while(ptrNode != NULL);
}
//命令行打印
name:MenAngel
age:
gender:boy
hobbys is array
方法一:value:语文
方法一:value:数学
方法一:value:英语
方法二:value:语文
方法二:value:数学
方法二:value:英语
scores is array
value:
course:语文
score:
value:
course:数学
score:
value:
course:英语
score:

    3.利用递归遍历xml文档(小于100层)

#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2; void printBlank(int level = )
{
while(level > )
{
cout<<" ";
level--;
}
}
int printXMLDocument(XMLElement *element,int level = )
{
printBlank(level);
cout<<element->Value()<<":"<<endl;
if(element->FirstChildElement() == NULL)
{
printBlank(level);
cout<<element->Name()<<" is "<<element->GetText()<<endl;
}
for(XMLElement *ptrElement = element->FirstChildElement();ptrElement;ptrElement = ptrElement->NextSiblingElement())
{
printXMLDocument(ptrElement,level + );
}
}
int main(int argv,char *argc[])
{
XMLDocument doc;
if(XML_SUCCESS != doc.LoadFile("test.xml"))
{
cout<<"load xml file failed!"<<endl;
return -;
}
XMLElement *root = doc.RootElement();
printXMLDocument(root);
return ;
}
root:
name:
name is MenAngel
age:
age is
gender:
gender is boy
hobbys:
value:
value is 语文
value:
value is 数学
value:
value is 英语
scores:
value:
course:
course is 语文
score:
score is
value:
course:
course is 数学
score:
score is
value:
course:
course is 英语
score:
score is

    4.打印XMLDocument装载的XML文件

//main.cpp
#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2; int main(int argv,char *argc[])
{
XMLDocument doc;
if(XML_SUCCESS != doc.LoadFile("test.xml"))
{
cout<<"load xml file failed!"<<endl;
return -;
}
XMLPrinter printer;
doc.Accept( &printer );
const char* xmlcstr = printer.CStr();
cout<<xmlcstr<<endl;
return ;
}
//命令行打印
<?xml version="1.0"?>
<root>
<name>MenAngel</name>
<age></age>
<gender>boy</gender>
<hobbys type="array">
<value>语文</value>
<value>数学</value>
<value>英语</value>
</hobbys>
<scores type="array">
<value>
<course>语文</course>
<score></score>
</value>
<value>
<course>数学</course>
<score></score>
</value>
<value>
<course>英语</course>
<score></score>
</value>
</scores>
</root>

    5.查询指定类型的属性

#include <iostream>
#include "tinyxml2/tinyxml2.h"
using namespace std;
using namespace tinyxml2; int main(int argv,char *argc[])
{
XMLDocument doc;
if(XML_SUCCESS != doc.LoadFile("test.xml"))
{
cout<<"load xml file failed!"<<endl;
return -;
}
XMLElement *ptrElement = doc.RootElement()->FirstChildElement("scores")->FirstChildElement("value")->NextSiblingElement();
cout<<"root scores value course = "<<ptrElement->FirstChildElement()->GetText()<<endl;
cout<<"root scores value score = "<<ptrElement->FirstChildElement()->NextSiblingElement()->GetText()<<endl;
int v1;
const char *s1 = new char[];
//查询取值
ptrElement->FirstChildElement("score")->QueryIntText(&v1);
cout<<"root scores value score = "<<v1<<endl;
//查询取属性值
doc.RootElement()->FirstChildElement("scores")->QueryStringAttribute("type",&s1);
cout<<"root scores attribute type = "<<s1<<endl;
return ;
}
root scores  value course = 数学
root scores value score =
root scores value score =
root scores attribute type = array

(3)TinyXml2的详解及使用的更多相关文章

  1. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

  2. 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)

    一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...

  3. EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解

    前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...

  4. Java 字符串格式化详解

    Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...

  5. Android Notification 详解(一)——基本操作

    Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...

  6. Android Notification 详解——基本操作

    Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...

  7. Git初探--笔记整理和Git命令详解

    几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...

  8. Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)

    Android XML shape 标签使用详解   一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...

  9. Node.js npm 详解

    一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...

随机推荐

  1. MYSQL获得查询记录的行号

    对于获得查询记录的行号这一功能,Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的ROWNUM,MS SQL Server 则在 2005 版本中提供了ROW_NUMBER()函数. ...

  2. css改变背景透明度

    透明往往能产生不错的网页视觉效果,先奉上兼容主流浏览器的CSS透明代码:.transparent{filter:alpha(opacity=90); -moz-opacity:0.9; -khtml- ...

  3. Spark RDD初探(一)

    本文概要 本文主要从以下几点阐述RDD,了解RDD 什么是RDD? 两种RDD创建方式 向给spark传递函数Passing Functions to Spark 两种操作之转换Transformat ...

  4. PHP类知识----clone方法上机实验

    <?php class mycoach { public function __construct($name,$age) { $this->name = $name; $this-> ...

  5. springboot整合mongodb问题1-Decimal128和BigDecimal的转换之mongodb转换器使用(转)

    转自:https://blog.csdn.net/weixin_41792559/article/details/79575524 1.Decimal128的了解由于mongodb4.3以上新加了De ...

  6. hdu 6096 String

    题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6096 ( 2017 Multi-University Training Contest - Team ...

  7. noi.ac #546 分组

    题目链接:戳我 题目描述 现在有n个字符串,你需要从中选出一些字符串,使得选出的字符串能被分组,满足每组大小为2,且可以从每组选出该组的两个字符串的一个非空公共后缀,使得每组选出的串互不相同. 输入格 ...

  8. nu.random.seed()如何理解

    结论: np.random.seed(a) # 按照规定的顺序生成随机数 # 参数a指定了随机数生成的起始位置: # 如果两处都采用了np.random.seed(a),且两处的参数a相同,则生成的随 ...

  9. codeforces402B

    Trees in a Row CodeForces - 402B The Queen of England has n trees growing in a row in her garden. At ...

  10. [CSP-S模拟测试]:答题(meet in the middle)

    题目传送门(内部题142) 输入格式 输入文件的第一行为两个数$n,P$. 接下来一行$n$为个正整数,表示每道题的分数. 输出格式 输出一行一个正整数,为至少需要获得的分数. 样例 样例输入: 2 ...