快速上手 TinyXML-2 不完全教程

article/2025/9/26 8:51:39

TinyXML-2 不完全教程

tinyxml2-logo.png

XML 作为程序开发中非常常用的数据文档之一,各个语言或是开发环境都有对应的用于处理 XML 文件的库。在 C++ 语言中,TinyXML-2 就是这样的一个库。

TinyXML-2 是一个简单,小巧,高性能的 C++ 的 XML 解析器,它能够容易地集成到其他程序中。

与 TinyXML-2 有关的两个网页如下:

  • GitHub 主页:https://github.com/leethomason/tinyxml2
  • 在线帮助文档:http://leethomason.github.io/tinyxml2/

TinyXML-2 的接入

在 tinyxml2 中有两个主要文件:

  • tinyxml2.cpp
  • tinyxml2.h

通常来讲,你仅仅需要将上面的两个主要的文件放到你的工程中,就可以使用它了。在编译时只需要将这两个和其他的源文件一起编译即可。

另外,还有一个测试文件:

  • xmltest.cpp

从这个文件里,我们可以看到关于 tinyxml2 的很多用法。不过仅仅是使用 tinyxml2 的话,可以暂时忽略这个文件。

使用 TinyXML-2 解析 XML 文件

通过 TinyXML-2 读取 XML 文件很简单,仅仅通过下面的两行代码,就能将一个 XML 文件解析到 XMLDocument 对象中:

XMLDocument doc;
doc.LoadFile( "dream.xml" );

在解析到 XMLDocument 对象中后,就可以通过这个对象来获取这个 XML 文件中的所有信息。这个对象跟其他的 C++ 对象一样,能够在栈上建立,也可以使用 new 或 delete 关键字在堆上创建或删除。

下面是一段读取和遍历 XML 文件的所有内容的代码,这也是这篇文章中最重要的部分了,如果看懂了的话,那么后面的内容就不用再看了:

这段代码也在这里 https://gist.github.com/Lee-swifter/traversingXMLUsingTinyXML,大家帮忙点个赞哈。。。

#include <iostream>
#include "tinyxml2.h"using namespace std;
using namespace tinyxml2;void traversingXML(XMLNode* node) {if(node == nullptr)return;if(node->ToDeclaration()) {auto declaration = dynamic_cast<XMLDeclaration*>(node);cout << "XML 声明,value=" << declaration->Value() << endl;}if(node->ToElement()) {auto element = dynamic_cast<XMLElement*>(node);cout << "XML 元素,name=" << element->Name() << ", value=" << element->Value() << endl;const XMLAttribute* attribute = element->FirstAttribute();while (attribute != nullptr) {cout << "\t属性 " << attribute->Name() << "=" << attribute->Value() << endl;attribute = attribute->Next();}}if(node->ToText()) {auto text = dynamic_cast<XMLText*>(node);cout << "XML 文本:" << text->Value() << endl;}if(node->ToComment()) {auto comment = dynamic_cast<XMLComment*>(node);cout << "XML 注释:" << comment->Value() << endl;}if(node->ToUnknown()) {auto unknown = dynamic_cast<XMLUnknown*>(node);cout << "XML 未知:" << unknown->Value() << endl;}if(node->ToDocument()) {auto document = dynamic_cast<XMLDocument*>(node);cout << "XML 文档:" << document->ErrorName() << endl;}if(node->NoChildren()) {return;}XMLNode* child = node->FirstChild();while(child != nullptr) {traversingXML(child);child = child->NextSibling();}
}int main(int argc, const char * argv[]) {XMLDocument xmlDocument;XMLError error = xmlDocument.LoadFile("test.xml");if(error != XML_SUCCESS) {std::cout << "读取 xml 失败:" << xmlDocument.ErrorStr() << endl;return EXIT_FAILURE;}traversingXML(&xmlDocument);return EXIT_SUCCESS;
}

但是在详细解析这段代码之前,我们需要了解 XMLDocument 的内存模型,才能进一步分析这段代码。

TinyXML-2 的内存模型

TinyXML-2 类型

TinyXML-2类图.png

上面这个图是 TinyXML-2 中用于表示 XML 内容的几个类的图。可见 TinyXML-2 将 XML 中的所有元素都归为 XMLNode。XMLNode 是一个抽象类,因此其继承出几种不同的类型以区分 XML 中的不同内容:

  • XMLDocument 表示一个 XML 文档
  • XMLElement 表示一个 XML 的元素
  • XMLComment 表示一个 XML 中的注释
  • XMLDeclaration 表示 XML 的声明,一般都是在 XML 最前面
  • XMLText 表示一个 XML 中的文本信息
  • XMLUnknow 未知的类型

这些类型光说一下可能不直观,所以,先放上一张示例图:
tinyxml2类型示例图.png

TinyXML-2 在内存中使用兄弟孩子表示法来表示生成 XML 的一个树,在 XMLNode 中最重要的两个方法就是:

  • const XMLNode * FirstChild() const
  • const XMLNode * NextSibling() const

TinyXML-2 中的兄弟孩子表示法

这两个方法是在兄弟孩子表示法中用于遍历的常用函数。对于兄弟孩子表示法不熟的人,看一下这张图:
兄弟孩子表示法.jpg

在这里,我们可以只需要将图中的所有节点看成一个 XMLNode 对象就明白了。通过上面的两个方法就可以递归遍历一个 XML 中的所有节点。

对于一个 XMLNode,可以通过 Value() 方法获取其内容,而且可以通过对应的 ToXXX 方法,安全的转换为其子类型。

TinyXML-2 对 XML 的操作

结合上面所说的两点,一个遍历 XML 的代码就可以出来了:

void traversingXML(XMLNode* node) {//查看 node 节点printf(node->Value());if(node->NoChildren())return;XMLNode* child = node->FirstChild();while(child != nullptr) {traversingXML(child);child = child->NextSibling();}
}

如果需要更改 XML 的话,仅仅需要创建出 XMLNode 然后对其进行操作,并添加到其他的节点上。但是这里需要特别注意的一点是:任何 XMLDocument 的子节点,例如 XMLElement、XMLText 等,只能通过调用对应的方法来创建,即 XMLDocument::NewElement、XMLDocument::NewText 这种方法。尽管你可以拥有这些节点对象的指针,这些子节点仍然归属于其 XMLDocument 对象。当 XMLDocument 对象被删除时,它所包含的所有节点也会被删除。

对于一个 XML 来讲,最需要关注的就是这个 XML 对应的 XMLDocument 对象了。它可以用来创建子节点,并进行一些最主要的操作。对于节点的插入和删除,可以使用 XMLNode 的下面的一些方法:

  • XMLNode * InsertFirstChild(XMLNode *addThis)
  • XMLNode * InsertAfterChild(XMLNode *afterThis, XMLNode *addThis)
  • XMLNode * InsertEndChild(XMLNode *addThis)
  • void DeleteChild(XMLNode *node)
  • void DeleteChildren()

例如:下面的代码将创建一个 XML 文件:

void createXML() {XMLDocument document;XMLDeclaration* declaration = document.NewDeclaration("xml version='1.0' encoding='utf-8' standalone='yes'");XMLComment* comment = document.NewComment("这是一个注释");XMLUnknown* unknow = document.NewUnknown("Unknow 类型");XMLElement* root = document.NewElement("svg");root->SetAttribute("height", "1080");root->SetAttribute("widht", "1920");root->SetAttribute("viewBox", "0 0 1920 1080");XMLElement* g = document.NewElement("g");XMLElement* path = document.NewElement("path");path->SetAttribute("stroke-width", "3.5");XMLText* text = document.NewText("text int path tag.");path->InsertEndChild(text);g->InsertEndChild(path);root->InsertEndChild(g);document.InsertEndChild(declaration);document.InsertEndChild(comment);document.InsertEndChild(unknow);document.InsertEndChild(root);document.SaveFile("test_save.xml");
}

其创建出来的 XML 文件如下:

<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<!--这是一个注释-->
<!Unknow 类型>
<svg height="1080" widht="1920" viewBox="0 0 1920 1080"><g><path stroke-width="3.5">text int path tag.</path></g>
</svg>

使用 TinyXML-2 保存 XML 文件

想要将 XML 保存到文件中时,仅需要调用下面的方法:

XMLDocument doc;
...
doc.SaveFile( "foo.xml" );

分割线图片.png

几个需要注意的地方

这里是关于其主页上的几个特点的翻译,如果想快速上手 tinyxml2,并觉得自己不会踩坑,可以直接跳过。

文件编码

在解析 XML 时,TinyXML-2 仅使用 utf-8 编码,并假定所有的 XML 文件都是用 utf-8 进行编码的。

加载/保存的文件名将会不加修改地传递给底层操作系统。

空白字符

保留空白字符(默认)

Microsoft 关于空白字符的处理有一篇很牛逼的文章:http://msdn.microsoft.com/en-us/library/ms256097.aspx

在默认情况下,TinyXML-2 用一种合理的方式保留空白字符。按照 XML 规范的要求,所有newlines / carriage-returns / line-feeds 都被规范化为换行字符。

在文本中的空白字符将会保留。例如:

<element> Hello, World</element>

这个 XML 中,Hello前面的空格和,后面的两个空格将会被保留。在文本中的换行符也将会被保留,例如下面的 XML:

<element> Hello again,
World</element>

但是,在元素之间的空白字符不会被保留。因为跟踪和报告元素之间的空白内容是很尴尬的,而且通常也没有任何价值,于是乎,TinyXML-2 会将下面的两个 XNL 认作相同的内容:

<document>
<data>1</data>
<data>2</data>
<data>3</data>
</document><document><data>1</data><data>2</data><data>3</data></document>

删除空白字符

某些应用程序更希望将空白字符删掉,TinyXML-2 可以通过向 XMLDocument 的构造函数传入空白字符的参数来支持,默认情况下是保留空白字符。

当你使用 COLLAPSE_WHITESPACE 来删除空白字符时,TinyXML-2 将会

  • 删除前导和末尾的空白字符
  • 将换行符转换为一个空白字符
  • 将连续的空白字符折叠成一个空白字符

但需要注意的是,使用COLLAPSE_WHITESPACE会有性能影响,它本质上将倒是 XML 被解析两次。

错误报告

TinyXML-2 如果在解析 XML 时发生错误,那么它将会报告错误发生所在行的行号。此外,所有节点(元素、声明、文本、注释等)和属性在解析时都有一个行号记录。这样的话,应用程序就可以对解析的XML文档执行额外的验证。

特殊字符

TinyXML-2 能够识别一些定义好的特殊字符,即:

&amp; &
&lt; <
&gt; >
&quot; "
&apos; '

在读取 XML 文档时,这些字符将会别识别为他们的 UTF-8 的值。例如,如果 XML
中一段文本是:

Far &amp; Away

如果你调用从这个 XMLText 对象调用 Value() 获取其值时,将会得到 “Far & Away”。


http://chatgpt.dhexx.cn/article/SFr37HKO.shtml

相关文章

开源库TinyXML2简介及使用

TinyXML2是一个开源、简单、小巧、高效的C XML解析器&#xff0c;它只有一个.h文件和一个.cpp文件组成&#xff0c;可以轻松集成到其它程序中。它解析XML文档并从中构建可以读取、修改和保存的文档对象模型(Document Object Model, DOM)。它不能解析DTD(Document Type Definiti…

c/c++操作xml库-Tinyxml2入门及高级用法

一、概念 TinyXML2是一个开源、简单、小巧、高效的C XML解析器&#xff0c;它只有一个.h文件和一个.cpp文件组成&#xff0c;可以轻松集成到其它程序中。它解析XML文档并从中构建可以读取、修改和保存的文档对象模型(Document Object Model, DOM)。它不能解析DTD(Document Typ…

关于Anaconda卸载干净的问题【已解决】

在卸载anaconda时&#xff0c;为了卸载干净&#xff0c;一般会在win10自带的 应用与功能中选择anaconda 进行卸载。 &#xff0c;也可以用anaconda文件中卸载程序Uninstall-Anaconda3.exe进行卸载。 然后再把相应路径下的剩余文件删掉。 但是&#xff01; 这还不够&#xff0c…

anaconda卸载后重装问题

记录一下anaconda卸载后&#xff0c;重新安装后缺少很多文件&#xff0c;重装后打开Anaconda Navigator&#xff0c;发现内容一片空白&#xff0c;软件也不见了&#xff0c;库也不见了&#xff0c;开始菜单也没有anaconda和anaconda prompt&#xff0c;只有如下很少的文件。网上…

如何彻底卸载Anaconda3

阅览了其他大神的卸载文章后&#xff0c;如 https://blog.csdn.net/qq_40605139/article/details/95249601 这篇就给了我很多指导&#xff0c;但我在运行第一句的 conda install anaconda-clean 后就出错了&#xff0c;提示截图如下&#xff1a; 然后就是各种百度&#xff0c;…

Anaconda卸载后重装过程

文章目录 前言一、卸载二、删除注册表三、下载安装包四、安装五、改环境变量六、检验参考文章 前言 因为之前装虚拟机的时候清理磁盘被迫卸掉anaconda&#xff0c;现在又要用jupyter notebook写作业&#xff0c;所以重新装了一遍&#xff0c;记录一下过程备用&#xff0c;也是…

anaconda卸载后重装的悲剧

在经历了无比绝望的一天后&#xff0c;我终于在意志消磨完的最后一刻成功完成了anaconda的卸载重装&#xff0c;这一天过的可以说是非常绝望了。上午还在开开心心的准备下载pytorch库进行学习&#xff0c;结果在更新依赖库的时候没有使用虚拟环境结果导致anaconda崩了&#xff…

CentOS安装/卸载Anaconda(图文详解)

目录 一、Anaconda下载 二、安装Anaconda 三、添加环境 四、卸载 1.删除anaconda文件目录 2.清理.bashrc中的Anaconda路径 一、Anaconda下载 众所周知的原因&#xff0c;从官网下载Anaconda非常慢&#xff0c;因此为了加速下载&#xff0c;这里我们采取清华源下载。 不…

Anaconda安装、查看、卸载第三方库

Anaconda安装第三方库&#xff1a; 下载第三方库&#xff1a;下载地址&#xff1a;https://www.lfd.uci.edu/~gohlke/pythonlibs/ 1、CtrlF 查找 2、下载&#xff0c;点击即可&#xff0c;注意下载的文件要与python环境相匹配 3、将下载的 .whl文件放入...yourpath....\Ana…

恢复anaconda环境, 卸载anaconda, 重装anaconda

在重装anaconda前思考一下是因为什么原因才要重装&#xff0c;如果是因为自己原先的配置好的环境变量在更新时候错乱了&#xff0c;其实可以通过回滚来回复的。 回滚 如果只是为了回复anaconda的环境&#xff0c;其实可以通过命令首先查看anaconda的 环境的历史记录&#xff0…

conda 的安装和卸载

conda 的安装和卸载 针对 ubuntu20.04 ubuntu20.04 是 “西柚云” 主要使用的操作系统 西柚云官网 文章目录 conda 的安装和卸载安装卸载重装 安装 下载 conda 的安装脚本&#xff08;这里使用清华大学的镜像&#xff09; cd ~ # 推荐将 conda 安装在家目录下 wget -c https…

彻底卸载并重装Anaconda环境与Python的方法

本文介绍在Windows平台下&#xff0c;彻底删除Anaconda环境与其自带Python版本&#xff0c;并进行重新安装的方法。 最近&#xff0c;由于原有Anaconda环境中的部分第三方库出现了冲突的情况&#xff0c;且基于“Anaconda Prompt (anaconda3)”也无法升级Anaconda与相关库了&am…

[转载] 怎样彻底卸载anaconda?

彻底卸载anaconda的方法&#xff1a;1、安装Anaconda-Clean package&#xff1b;2、执行【anaconda-clean --yes】命令&#xff1b;3、运行Uninstall-Anaconda3.exe程序即可。 1、安装 Anaconda-Clean package 记得要以管理员身份打开 打开 Anaconda Prompt&#xff0c; 输…

超详细彻底卸载Anaconda详细教程

一、在开始处打开Anaconda Prompt 二、打开后&#xff0c;输入conda install tqdm -f命令并按回车键 conda install tqdm -f三、之后页面会出现一个WANNING&#xff0c;这个我们不用在意&#xff0c;然后会出现一个y/n提示框&#xff0c;在这里我们输入y或者Y y四、输入cond…

关于anaconda的使用和Python库的安装、卸载

本文主要内容 一、anaconda1、anaconda的作用2、一些常用的anaconda命令 二、Python库的安装方法一&#xff1a;pycharm解释器中进行添加&#xff08;一般不推荐&#xff0c;速度慢&#xff09;方法二、控制面板中进行安装&#xff08;最常用&#xff09;方法三、离线安装 三、…

Unbuntu卸载anaconda(最新最全亲测)

文章目录 前言一、删除anaconda文件夹二、删除Anaconda的环境变量总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;随着人工智能的不断发展&#xff0c;机器学习这门技术也越来越重要&#xff0c;很多人都开启了学习机器学习&#x…

一、如何完全卸载Anaconda(如何下载Anaconda-Clean package)

因为一些不可描述的原因必须要卸载Anaconda。 一、在我的Anaconda不可用后&#xff0c;按照其他博主的方法进行尝试卸载Anaconda&#xff0c;发现Anaconda--clean安装不可使用&#xff0c; 二、之后我苦苦寻找方法&#xff0c;发现都不怎么可行&#xff0c;直到我碰到一位博主的…

如何卸载、删除Anaconda?

Anaconda这么好用&#xff0c;为啥要删呢&#xff1f;当然是我之前装得乱七八糟&#xff0c;导致现在心情不好。我要把它全部删掉&#xff01; ok&#xff0c;开始~ 删除思路&#xff1a; 首先利用anaconda-clean清理包清理配置文件&#xff0c;然后直接用安装目录下的卸载程序…

anaconda 完全卸载——重装

由于安装环境的时候不知道什么地方出错了&#xff0c;导致conda下载不了新的包&#xff0c;也不能更新现有的包&#xff0c;所以采取卸载anaconda并重装的方法&#xff08;简答粗暴&#xff09; 卸载 在网上搜集资料&#xff0c;发现卸载anaconda的方法五花八门&#xff0c;而…

如何彻底卸载Anaconda?

文章目录 0.前言1.解决方案1.1方案11.2方案2 2.参考文档 0.前言 本机Win10。  最好的参考文档是官方文档Uninstalling Anaconda。除此以外&#xff0c;再辅助以其他文档&#xff0c;就能达到如标题所示的目的。整个删除过程不难。 1.解决方案 1.1方案1 官方推荐的方案是两种…