写这篇文章纯属偶然。

我很少接触xml,工作上也没使用过。即使使用,也是别人做好的接口,直接调用。最近的一个项目中,因为某些策略问题,造成项目的代码十分混乱,东拼西凑,做成了个不像样的东西。其中有部分是设备端与PC端的网络协议传输,使用到了自定义的xml协议,因为某些原因,这个协议不断地改进但未同步更新,幸亏做了兼容,但部分新加协议未在设备端更新,所以要添加进去,不过某同事忙于其它事务,所以只有我上了(个中故事等有空写篇文章出来)。

闲话少说,为了研究一下xml,自己抽空练习使用了一下tinyxml,为了避免与公司发生不必要的纠纷,特别使用了tinyxml第二版本(公司代码使用第一版本),特地在周末写程序。

tinyxml的第二版本改动很多,参考官方网站说明。

在使用前要包含头文件并要使用tinyxml2命令空间。如下:

#include "tinyxml2.h"
using namespace tinyxml2;

下面给出创建xml的示例函数:

// 创建xml示例
int createXML(const char* xmlFile)
{XMLDocument* doc = new XMLDocument();if (doc == NULL){return -1;}// decXMLDeclaration *dec = NULL;dec = doc->NewDeclaration("xml version=\"1.0\" encoding=\"gb2312\" standalone=\"yes\"");//dec = doc->NewDeclaration();  // 默认为utf-8if (dec == NULL){return -1;}doc->LinkEndChild(dec);// 根元素XMLElement* root = doc->NewElement("Root");if (root == NULL){return -1;}root->SetAttribute("ver", "1.0");doc->LinkEndChild(root);// 第一级子节点XMLElement* fstEle = doc->NewElement("subClass1");XMLText* fstText = doc->NewText("Text1");fstEle->SetAttribute("attribute1", "foo");fstEle->SetAttribute("attribute2", "bar");fstEle->LinkEndChild(fstText);root->LinkEndChild(fstEle);// 第二个同级节点XMLElement* fstEle1 = doc->NewElement("subClass2");XMLText* fstText1 = doc->NewText("Text2");fstEle1->SetAttribute("attribute1", "foo");fstEle1->SetAttribute("attribute2", "bar");fstEle1->LinkEndChild(fstText1);root->LinkEndChild(fstEle1);// 第三个同级节点,但没有Text,可以再设一级子节点XMLElement* thdEle = doc->NewElement("subClass3");thdEle->SetAttribute("attribute1", "foo");root->LinkEndChild(thdEle);// 第三个节点的子节点XMLElement* sndEle = doc->NewElement("sub_subClass1");XMLText* sndText = doc->NewText("subText");sndEle->SetAttribute("attribute", "foobar");sndEle->LinkEndChild(sndText);thdEle->LinkEndChild(sndEle);// 第四个节点XMLElement* fstEle2 = doc->NewElement("subClass4");XMLText* fstText2 = doc->NewText("Text4");fstEle2->SetAttribute("attribute1", "foo");fstEle2->SetAttribute("attribute2", "bar");fstEle2->LinkEndChild(fstText2);root->LinkEndChild(fstEle2);///// 保存,打印doc->SaveFile(xmlFile);XMLPrinter printer;doc->Print(&printer);const char* xmlcstr = printer.CStr();// 打印printf("xml buffer: \n");printf("%s\n", xmlcstr);///#if 0XMLElement* rootEle = NULL;XMLElement* node = NULL;rootEle = doc->RootElement();if (rootEle == NULL) return -1;findNode(rootEle, "sub_subClass1", node);// textconst char* text = NULL;findText(node, &text);printf("---- text: %s\n", text);const char* test_value = NULL;findAttribute(node, "apple", test_value);printf("xxxxx: %s\n", test_value);#endifdelete doc;doc = NULL;return 0;
}

结果如下:

<?xml version="1.0" encoding="gb2312" standalone="yes"?>
<Root ver="1.0"><subClass1 attribute1="foo" attribute2="bar">Text1</subClass1><subClass2 attribute1="foo" attribute2="bar">Text2</subClass2><subClass3 attribute1="foo"><sub_subClass1 attribute="foobar">subText</sub_subClass1></subClass3><subClass4 attribute1="foo" attribute2="bar">Text4</subClass4>

下面再给出解析xml内容的示例函数:

int findElement(XMLElement* root)
{if (root == NULL) return -1;XMLElement* ele = NULL;int i = 0;for (ele = root->FirstChildElement(); ele; ele = ele->NextSiblingElement()){printf("Element: %s Text: %s\n", ele->Value(), ele->GetText());const XMLAttribute* attr = NULL;for (attr = ele->FirstAttribute(), i = 0; attr; attr = attr->Next(), i++){printf("attr(%d) (%s: %s)\n", i, attr->Name(), attr->Value());    }if (ele->FirstChildElement()){printf("sub %s: \n", ele->Value());findElement(ele);   // 递归查找元素}}return 0;
}// 解析xml示例
int parseXML(const char* xmlFile)
{XMLDocument* doc = new XMLDocument();if (doc == NULL){return -1;}doc->LoadFile(xmlFile);doc->Print();// 声明//todo// 根XMLElement* root = doc->RootElement();if (root == NULL) return -1;// 元素属性const XMLAttribute* attr = NULL;for (attr = root->FirstAttribute(); attr; attr = attr->Next()){printf("root: %s attr (%s: %s)\n", root->Value(), attr->Name(), attr->Value());    }// 查找元素并打印findElement(root);return 0;
}

结果如下:

root: Root attr (ver: 1.0)
Element: subClass1 Text: Text1
attr(0) (attribute1: foo)
attr(1) (attribute2: bar)
Element: subClass2 Text: Text2
attr(0) (attribute1: foo)
attr(1) (attribute2: bar)
Element: subClass3 Text: (null)
attr(0) (attribute1: foo)
sub subClass3:
Element: sub_subClass1 Text: subText
attr(0) (attribute: foobar)
Element: subClass4 Text: Text4
attr(0) (attribute1: foo)
attr(1) (attribute2: bar)

tinyxml2的资料比较少,官方的示例及文档是比较权威的,可以参考一下。根据我的使用及查阅的资料,下面列举与第一版本改动的地方。

1、源文件个数减少至2个,即一个头文件(tinyxml2.h),一个实现文件(tinyxml2.cpp)。

2、加入了tinyxml2的命名空间。

3、对类名称作了修改,将TiXml**改为XML**,比如TiXmlElement改为XMLElement。

4、少了很多new,只有XMLDocument需要new,其它均由该类的方法进行封装。如下:

旧:

TiXmlDeclaration *dec= new TiXmlDeclaration("1.0","","");

新:

XMLDeclaration *dec = doc->NewDeclaration("xml version=\"1.0\" encoding=\"gb2312\" standalone=\"yes\"");

旧:

TiXmlElement *ele= new TiXmlElement("Root");  

新:

XMLElement* root = doc->NewElement("Root");

5、网上有人讨论是否需要手动delete掉new出来的类,我没有在实际工作中使用到,所以不发表意见。在第二版中,示例代码只有XMLDocument才用delete,其它没有使用。所以上述代码也在最后delete。

资源:

tinyxml网站:http://www.grinninglizard.com/tinyxml2/

git仓库地址:https://github.com/leethomason/tinyxml2.git

迟,于2013年9月8日午后

初步接触TinyXML2相关推荐

  1. 初步接触houdini---零零散散

    选修了数字娱乐技术基础 大体上分为以下几个板块的学习: 一:数学基础知识 矢量,点乘,三角函数,等等(记不太清了).可惜老师讲了整整两节课,基本原理略知一二,关于在houdini上做一个光学模型我是真 ...

  2. GMSSL开源库--初步接触SM2

    2021SC@SDUSC 目录 一.整体情况 二.sm2_asn1.c 一.整体情况 在有关OPENSSL的一本书上看到了OPENSSL部分目录功能说明,Crypto目录中存放OpenSSL所有加密算 ...

  3. pl/sql command window 初步接触

    pl/sql command window基本操作 PL/SQL Developer应用两年了,今天第一次应用command window. command window类似于sqlplus窗口: 1 ...

  4. VS 2008 Feature Pack界面开发学习笔记之初步接触

    作者:朱金灿 来源:http://blog.csdn.net/clever101/ 打算将最近学到的VS 2008 Feature Pack界面开发的一些心得写出来.VS 2010都出来了,我还刚用V ...

  5. Reat学习01——初步接触与安装

    React安装看起来还是很简单的,不需要想webpact等根据一样,需要先安装然后配置.React提前配置好的,真正做到了一键式的安装与使用. Installation:npm install -g ...

  6. 测试微信小程序图片预览功能(因初步接触之了解到了不能使用本地图片,以下为公司产品图片)...

    转载于:https://www.cnblogs.com/lb0602/p/8006146.html

  7. spring mvc 初步接触学习笔记

    1.使用maven导入spring mvc web 的jar 包 最新语句 <dependency> <groupId>org.springframework</grou ...

  8. python学习-注释、语法、整数、浮点数初步接触

    文章目录 注释 编码特点 自定义函数 题外话 注释 井号(#),规范写法是"# " 井号+空格 python的代码风格是PEP8 python能够根据赋值自己定义数据类型,不需要单 ...

  9. common lisp 学习第一天 初步接触

    http://common-lisp.net/project/lispbox/ lispbox 集成了Emacs.Slime和CCL. 解压后直接运行lispbox.bat即可 //(quote x) ...

最新文章

  1. 使用dd命令复制ASM磁盘的spfile
  2. 揭秘大型网站架构进化之路
  3. 常用的 css 样式 记录
  4. 保存web.config文件(转载)
  5. 科大星云诗社动态20210813
  6. Spring4中的@Value的使用(学习笔记)
  7. seaborn常用的10种数据分析图表
  8. Redis分布式锁问题
  9. 第3章   IP寻址
  10. anaconda环境中使用sudo python报错
  11. rabbitmq视频教程,面试官:
  12. [原创] 对于深度学习(deep learning)在工业界的应用现状和突破 [by matthewbai]
  13. 如何修改计算机mac地址吗,如何修改电脑的Mac地址
  14. C语言_4 循环结构;一些例题
  15. 图示代码,轻松解决IV值计算问题(python)
  16. 初谈证券交易系统开发核心
  17. 树莓派+SAKS扩展板实现数码管时钟
  18. oracle中vim设置行号,vim的常用操作
  19. 怡和嘉业在创业板上市:总市值约186亿元,前三季度业绩同比翻倍
  20. Python turtle绘制——癸卯(兔)年卯兔图

热门文章

  1. 马斯克加入推特董事会引发员工担忧:可能改变审查规则
  2. Kindle的对手来了?华为首款鸿蒙墨水平板国行发布时间曝光...
  3. 马斯克:如果我不担任CEO 特斯拉就会完蛋
  4. 微软已确认放弃Windows 10X操作系统 新功能下放
  5. 降价到心痛也无人问津!这款手机成绝唱...
  6. 蛋壳公寓CEO高靖被限制消费
  7. 3399元起!120Hz瞳孔屏+65W超级闪充,一加 8T今日发布
  8. 制动方面存隐患 上汽通用召回2215辆别克、雪佛兰等车型
  9. 曾经辉煌无限,如今员工持续大量流失,集团目前仅剩10余人
  10. 微信小程序直播助力深圳线上购物节 数百场品牌小程序开播