最近项目中使用到xml,最终选用了tinyxml2,学习后写个总结。

TinyXml2 主要类型:

XMLNode: XMLNode is a base class for every object that is in the XMLDocument Object Model (DOM), except XMLAttributes.Nodes have siblings, aparent, and children which can be navigated. A node is always in a XMLDocument.The type of a XMLNode can be queried, and it can be cast to its more definedtype.

XMLDocument: A Document binds together all the functionality.It can be saved,loaded, and printed to the screen.All Nodes are connected and allocated to aDocument.If the Document is deleted, all its Nodes are also deleted.

A XMLDocumentallocates memory for all its Nodes.When the XMLDocument gets deleted, all itsNodes will also be deleted.

A Document cancontain:         Element   (container or leaf)

Comment(leaf)

Unknown(leaf)

Declaration(leaf )

XMLDeclaration: In correct XML the declaration is the first entry in the file.

<?xmlversion="1.0" standalone="yes"?>

TinyXML-2will happily read or write files without a declaration,however.    The text of the declaration isn'tinterpreted. It is parsed and written as a string.

XMLComment: 对应于XML文档中的注释部分的对象。

XMLElement: The element is a container class. It has a value, the elementname,and can contain other elements, text, comments, and unknowns.Elements alsocontain an arbitrary number of attributes.

XMLText:         Note that a text nodecan have child element nodes, for example:

<root>Thisis <b>bold</b></root>

Atext node can have 2 ways to output the next. "normal" output

andCDATA. It will default to the mode it was parsed from the XML file and

yougenerally want to leave it alone, but you can change the output mode with

SetCData()and query it with CData().

XMLAttribute: An attribute is a name-value pair. Elements have an arbitrary

numberof attributes, each with a unique name.

@noteThe attributes are not XMLNodes. You may only query theNext() attribute in alist.

XMLUnknown:  Any tag that TinyXML-2doesn't recognize is saved as an unknown. It is a tag of text, but should notbe modified.It will be written back to the XML, unchanged, when the file issaved.DTD tags get thrown into XMLUnknowns.

从上面的介绍可知,除了XMLAttribute以外,其他的都继承自XMLNode

tinyxml2把xml文档建立成一棵DOM树,具体实现用的是firstchild–nextsiblingtree,下图是对该树的模型的一个简单介绍:

firstchild-nextsibling是一种多叉树常用的实现方法,每个结点只需要知道它的第一个孩子结点(first child node)和它的下一个兄弟结点(next sibling node),这样一整棵树的结构就会建立起来,也可以用根结点的指针为起点来对整棵树进行遍历。

写xml文件,有些意外的XMLText应该可以插入子节点,但是最后生成的文件并没有子节点。

static void Write()
{XMLDocument Doc;XMLDeclaration* pDecaration=Doc.NewDeclaration("This is a Declaration!");Doc.LinkEndChild(pDecaration);XMLComment* pComment = Doc.NewComment("This is a Document Comment!");Doc.LinkEndChild(pComment);XMLElement* pElementRoot = Doc.NewElement("School");Doc.LinkEndChild(pElementRoot);XMLComment* pCommentRoot = Doc.NewComment("This is a School Comment!");pElementRoot->LinkEndChild(pCommentRoot);{XMLElement* pElementTeachers = Doc.NewElement("teachers");pElementRoot->LinkEndChild(pElementTeachers);pElementTeachers->LinkEndChild(Doc.NewElement("Wang"));pElementTeachers->LinkEndChild(Doc.NewElement("Li"));pElementTeachers->LinkEndChild(Doc.NewElement("Zhao"));}XMLElement* pElementStudents = Doc.NewElement("students");pElementRoot->LinkEndChild(pElementStudents);{XMLElement* pElementLiMing = Doc.NewElement("LiMing");pElementLiMing->SetText("Li Ming is a good Student!");pElementLiMing->SetAttribute("sex", "male");pElementLiMing->SetAttribute("height", 174);pElementLiMing->SetAttribute("weight", 80.4);pElementLiMing->SetAttribute("Is_good_at_math", false);pElementStudents->LinkEndChild(pElementLiMing);}{XMLElement* pElementCuiHua = Doc.NewElement("CuiHua");XMLElement* pElementSex = Doc.NewElement("sex");pElementSex->SetText("female");XMLText* pText = Doc.NewText("this is a Text!");pText->LinkEndChild(pElementSex);pElementCuiHua->LinkEndChild(pText);pElementStudents->LinkEndChild(pElementCuiHua);}{XMLElement* pElementHanmeimei = Doc.NewElement("Hanmeimei");pElementStudents->LinkEndChild(pElementHanmeimei);XMLText* pTextCData = Doc.NewText("this is a CData Text:if (a < b && a < 0)");pTextCData->SetCData(true);pElementHanmeimei->LinkEndChild(pTextCData);}XMLUnknown* pUnknow = Doc.NewUnknown("this is a Unknow!");pElementRoot->LinkEndChild(pUnknow);Doc.SaveFile("test.xml");
}

生成的文件:

<?This is a Declaration!?>
<!--This is a Document Comment!-->
<School><!--This is a School Comment!--><teachers><Wang/><Li/><Zhao/></teachers><students><LiMing sex="male" height="174" weight="80.400000000000006" Is_good_at_math="false">Li Ming is a good Student!</LiMing><CuiHua>this is a Text!</CuiHua><Hanmeimei><![CDATA[this is a CData Text:if (a < b && a < 0)]]></Hanmeimei></students><!this is a Unknow!>
</School>

读xml文件

static void Read()
{XMLDocument Doc;Doc.LoadFile("test.xml");XMLElement* pElementRoot = Doc.RootElement();{XMLElement* pElementTeachers = pElementRoot->FirstChildElement("teachers");pElementTeachers->FirstChildElement("Wang");pElementTeachers->FirstChildElement("Li");pElementTeachers->FirstChildElement("Zhao");}XMLElement* pElementStudents = pElementRoot->FirstChildElement("students"); {XMLElement* pElementLiMing = pElementStudents->FirstChildElement("LiMing");const char* pText=pElementLiMing->GetText();const char* pSex=pElementLiMing->Attribute("sex");int iHeight=pElementLiMing->IntAttribute("height");double dbHeight=pElementLiMing->DoubleAttribute("weight");bool bIsGood=pElementLiMing->BoolAttribute("Is_good_at_math");}{XMLElement* pElementCuiHua = pElementStudents->FirstChildElement("CuiHua");XMLNode* pNode=pElementCuiHua->FirstChild();XMLText* pText = pNode->ToText();//XMLElement* pElementSex = pText->FirstChildElement("sex");//const char* pSex = pElementSex->GetText();}{XMLElement* pElementHanmeimei = pElementStudents->FirstChildElement("Hanmeimei");XMLText* pTextCData = pElementHanmeimei->FirstChild()->ToText();bool bCData=pTextCData->CData();}
}

最后说下中文的问题,由于tinyxml2使用utf8编码,如果输入中文,输出的是乱码,以下是解决方案,使用字符转换,需要c++11的支持。

#include <string>
#include <vector>
#include <codecvt>
#ifdef UNICODE
typedef wchar_t tchar;
#else
typedef char tchar;
#endiftypedef std::basic_string < tchar, std::char_traits<tchar>, std::allocator<tchar> > tstring;
std::string unicode_to_utf8(std::wstring const& strUnicode)
{std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8;return cutf8.to_bytes(strUnicode);
}
std::wstring utf8_to_unicode(std::string const& strutf8)
{std::wstring_convert<std::codecvt_utf8<wchar_t>> cutf8;return cutf8.from_bytes(strutf8);
}
std::wstring gb2312_to_unicode(std::string const &strGb2312)
{std::vector<wchar_t> buff(strGb2312.size());
#ifdef _MSC_VERstd::locale loc("zh-CN");
#elsestd::locale loc("zh_CN.GB18030");
#endifwchar_t* pwszNext = nullptr;const char* pszNext = nullptr;mbstate_t state = {};int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> >(loc).in(state,strGb2312.data(), strGb2312.data() + strGb2312.size(), pszNext,buff.data(), buff.data() + buff.size(), pwszNext);if (std::codecvt_base::ok == res){return std::wstring(buff.data(), pwszNext);}return L"";
}std::string unicode_to_gb2312(std::wstring const& strUnicode)
{
#ifdef _MSC_VERstd::locale loc("zh-CN");
#elsestd::locale loc("zh_CN.GB18030");
#endifconst wchar_t* pwszNext = nullptr;char* pszNext = nullptr;mbstate_t state = {};std::vector<char> buff(strUnicode.size() * 2);int res = std::use_facet<std::codecvt<wchar_t, char, mbstate_t> >(loc).out(state,strUnicode.data(), strUnicode.data() + strUnicode.size(), pwszNext,buff.data(), buff.data() + buff.size(), pszNext);if (std::codecvt_base::ok == res){return std::string(buff.data(), pszNext);}return "";
}
inline std::string tstring_to_utf8(tstring const& strToConvert){
#ifdef UNICODEreturn unicode_to_utf8(strToConvert);
#elseauto strUnicode=gb2312_to_unicode(strToConvert);return unicode_to_utf8(strUnicode);
#endif
}
inline tstring utf8_to_tstring(std::string const& strToConvert){
#ifdef UNICODEreturn utf8_to_unicode(strToConvert);
#elseauto strUnicode = utf8_to_unicode(strToConvert);return unicode_to_gb2312(strUnicode);
#endif
}

这时候,我们可能需要对XMLElement,XMLDocument等做个wrapper,封装字符转换。感谢 ml232528给出的解决方案。

tinyxml2使用方法相关推荐

  1. TinyXML2使用方法及示例

    转自https://blog.csdn.net/liang_baikai/article/details/78783839 概述  TinyXML2是简单实用的开源的C++XML文件解析库,可以很方便 ...

  2. 树莓派(五)Tinyxml Tinyxml2的使用

    TinyXML2是simple.small.efficient开源的C++ XML文件解析库 优点:(1)对大部分的C/C++项目具有普适性.(2)使用较少的内存,速度变得更快.(3)没有C++的ST ...

  3. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群

    作者:Jeffrey Hunter 了解如何以低于 2,700 美元的费用在 Oracle Enterprise Linux 上安装并配置 Oracle RAC 11g 第 2 版开发集群. 本指南中 ...

  4. Java面试题大全2021版

    一.Java 基础 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Run ...

  5. qt中tinyxml2的基本使用方法

    TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译. 这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML ...

  6. tinyxml 读取文本节点_在Windows下使用TinyXML-2读取UTF-8编码包含中文字符的XML文件...

    TinyXML-2 是一个用 C++ 开发的小巧.高效的 XML 解析工具,它在 GitHub 网站上的链接为: https://github.com/leethomason/tinyxml2 .它的 ...

  7. 初步接触TinyXML2

    写这篇文章纯属偶然. 我很少接触xml,工作上也没使用过.即使使用,也是别人做好的接口,直接调用.最近的一个项目中,因为某些策略问题,造成项目的代码十分混乱,东拼西凑,做成了个不像样的东西.其中有部分 ...

  8. TinyXML2 入门教程

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

  9. TinyXML2使用教程

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

最新文章

  1. 【组队学习】【32期】推荐系统-新闻推荐系统实践
  2. mysql 事务 for update_mysql事务,select for update,及数据的一致性处理
  3. 专家:大数据等新技术助力信息融合
  4. Participate in E-sports【Java大数+二分】
  5. HTTPS重定向到HTTP
  6. 第二次课动手动脑的问题以及课后实验性的问题
  7. alibaba/Sentinel 分布式 系统流量防卫兵
  8. colorpicker插件和使用(直接能用真美好)
  9. Matlab打开prn文件,打印prn文件的方法和技巧,.prn用什么软件打开?
  10. opencms mysql_[转]OpenCms for MySql 安装图解
  11. 实现阿里云DDNS解析
  12. 系统辨识与自适应控制matlab程序_杂志精选 | 自适应声反馈抑制技术及其应用
  13. JOIN 7图:念念不忘必有回响
  14. 计算机学报在线阅读,计算机学报CHIN.pdf
  15. 中国互联网老总的经典妙语语录
  16. 漏洞工具包2015年态势回顾:规模与分布
  17. JavaScript 指南 - 使用对象
  18. kalilinux链接蓝牙音响_Kali Linux安装驱动并使用Blueman连接蓝牙耳机
  19. unity 创建Txt文件并写入数据
  20. ASUS路由器支持锐捷设置

热门文章

  1. 伏并网低电压穿越技术
  2. 网页设计:HTML常用的五种标签
  3. WPF 如何引入图标文件
  4. 大语言模型举例和相关论文推荐
  5. 理解ClangAST
  6. java计算机毕业设计小微企业人事管理系统源码+lw文档+系统+数据库
  7. 【语音智能平台】京东Alpha VS 讯飞开放平台 (二)
  8. Oracle数据库版本跟jdk,oracle的jdbc的版本与jdk对应关系
  9. mysql innodb_log_group_home_dir_InnoDB参数详解
  10. Java中数组的赋值拷贝