TinyXML2的一些用法

TinyXML2

      • 原始字符串字面量
    • TinyXML2
      • 1. XML文档操作
        • 1.1 LoadFile(const char* filename)
        • 1.2SaveFile(const char* filename)
        • 1.3RootElement()
        • 1.4Parse(const char* xml)
      • 2.元素操作
        • 2.1 FirstChildElement(const char* name = nullptr)
        • 2.2 NextSiblingElement(const char* name = nullptr)
        • 2.3 SetName(const char* name)
        • 2.4 DeleteChild(XMLElement* child)
      • 3. 属性操作
        • 3.1SetAttribute(const char* name, const char* value)
        • 3.2 Attribute(const char* name)
        • 3.3 DeleteAttribute(const char* name)
      • 4. 文本操作
        • 4.1 SetText(const char* text)
        • 4.2 GetText()
      • 5. 新建元素和节点
        • 5.1 NewElement(const char* name)
        • 5.2 InsertFirstChild(XMLNode* child)
        • 5.3 InsertEndChild(XMLNode* child)
      • 6. 错误处理
        • 6.1 ErrorID()
        • 6.2ErrorStr()
    • 附录:XML文件格式
      • 命名空间
      • 模式位置
      • 简单的XML文件
      • 复杂的XML文件

原始字符串字面量

  • 原始字符串字面量是 C++ 提供的一种字符串表示法,用来简化特殊字符的处理(例如换行符、反斜杠)和避免过多的转义字符。它的引入是为了让字符串更可读、更易于书写,尤其是涉及正则表达式、文件路径等场景。
  • 语法
原始字符串字面量以 R"delimiter(raw_characters)delimiter" 的形式表示:delimiter 是用户定义的分隔符,可以用任意字符,但不能包含空白字符或括号。
raw_characters 是原始字符串的内容,所有字符将被保留原样。
  • 特点
    • 支持多行字符串:原始字符串字面量可以直接包含换行符,而无需使用 \n。
    • 无需转义字符:在常规字符串中,特殊字符(如换行符 \n 或双引号 ")需要用反斜杠 \ 转义。
    • 灵活的分隔符:如果字符串中包含了 “)”,可以使用自定义分隔符避免冲突。
    std::string raw_str = R"delimiter(This is a raw string with ")".)delimiter";
    • 可嵌套引号:原始字符串字面量允许在字符串中直接包含双引号。
  • 使用方法同普通字符串一样。

TinyXML2

  1. TinyXML2 是一个轻量级的 XML 解析库,专为简单和快速设计,适合嵌入式系统、小型应用或需要解析/生成 XML 的程序。TinyXML2 的核心功能包括 XML 的读取、修改和写入。
  2. 跨平台:纯 C++ 编写,可在 Windows、Linux、macOS 等平台上使用。
  3. 无需外部依赖:仅需单个头文件和源文件(tinyxml2.h 和 tinyxml2.cpp)。

1. XML文档操作

1.1 LoadFile(const char* filename)

功能:将 XML 文档保存到文件。
参数:filename 是文件路径。
返回值:保存成功返回 XML_SUCCESS,否则返回错误码。

XMLDocument doc;//表示整个 XML 文件,负责加载、解析、保存。
if (doc.LoadFile("example.xml") != XML_SUCCESS) {std::cerr << "Failed to load XML file!" << std::endl;
}
1.2SaveFile(const char* filename)

功能:将 XML 文档保存到文件。
参数:filename 是文件路径。
返回值:保存成功返回 XML_SUCCESS,否则返回错误码。

if (doc.SaveFile("output.xml") != XML_SUCCESS) {std::cerr << "Failed to save XML file!" << std::endl;
}
1.3RootElement()

功能:获取 XML 文档的根元素。
返回值:指向根元素的指针,如果没有根元素返回 nullptr。

XMLElement* root = doc.RootElement();
if (!root) {std::cerr << "No root element found!" << std::endl;
} else {std::cout << "Root element: " << root->Name() << std::endl;
}
1.4Parse(const char* xml)

功能:直接解析 XML 字符串。
参数:xml 是一个 XML 格式的字符串。
返回值:解析成功返回 XML_SUCCESS,否则返回错误码。

const char* xml = "<Root><Child>Text</Child></Root>";
if (doc.Parse(xml) != XML_SUCCESS) {std::cerr << "Failed to parse XML string!" << std::endl;
}
示例// 1. 基本解析
XMLDocument doc;
// 解析简单的XML字符串
const char* xml = "<Root><Child>Hello</Child></Root>";
if (doc.Parse(xml) == XML_SUCCESS) {XMLElement* root = doc.FirstChildElement("Root");XMLElement* child = root->FirstChildElement("Child");const char* text = child->GetText();  // 获取 "Hello"
}// 2. 解析带属性的XML
const char* xmlWithAttr = R"(<Person id="1" name="John"><Age>30</Age><Address city="New York"><Street>Broadway</Street></Address></Person>
)";
if (doc.Parse(xmlWithAttr) == XML_SUCCESS) {XMLElement* person = doc.FirstChildElement("Person");const char* name = person->Attribute("name");  // 获取 "John"XMLElement* address = person->FirstChildElement("Address");const char* city = address->Attribute("city");  // 获取 "New York"
}// 3. 解析列表数据
const char* xmlList = R"(<Inventory><Item id="1" name="Apple" price="0.5"/><Item id="2" name="Banana" price="0.3"/><Item id="3" name="Orange" price="0.4"/></Inventory>
)";
class InventoryParser {
public:struct Item {int id;string name;double price;};static vector<Item> parseItems(const char* xml) {vector<Item> items;XMLDocument doc;if (doc.Parse(xml) == XML_SUCCESS) {XMLElement* inventory = doc.FirstChildElement("Inventory");for (XMLElement* elem = inventory->FirstChildElement("Item");elem != nullptr;elem = elem->NextSiblingElement("Item")) {Item item;item.id = elem->IntAttribute("id");item.name = elem->Attribute("name");item.price = elem->DoubleAttribute("price");items.push_back(item);}}return items;}
};// 4. 解析嵌套结构
const char* xmlNested = R"(<Company><Department name="Engineering"><Employee id="1"><Name>John Doe</Name><Position>Developer</Position><Skills><Skill>C++</Skill><Skill>Python</Skill></Skills></Employee></Department></Company>
)";
class CompanyParser {
public:static void parseEmployee(XMLElement* empElement) {string name = empElement->FirstChildElement("Name")->GetText();string position = empElement->FirstChildElement("Position")->GetText();vector<string> skills;XMLElement* skillsElem = empElement->FirstChildElement("Skills");for (XMLElement* skill = skillsElem->FirstChildElement("Skill");skill != nullptr;skill = skill->NextSiblingElement("Skill")) {skills.push_back(skill->GetText());}}
};// 5. 错误处理
class XMLParser {
public:static bool parseWithErrorHandling(const char* xml) {XMLDocument doc;XMLError err = doc.Parse(xml);switch (err) {case XML_SUCCESS:return true;case XML_ERROR_FILE_NOT_FOUND:cerr << "XML file not found!" << endl;break;case XML_ERROR_PARSING_ELEMENT:cerr << "Error parsing element!" << endl;break;case XML_ERROR_PARSING_ATTRIBUTE:cerr << "Error parsing attribute!" << endl;break;default:cerr << "Unknown XML error!" << endl;}return false;}
};// 6. 配置文件解析
const char* configXml = R"(<Config><Database><Host>localhost</Host><Port>3306</Port><Username>root</Username><Password>secret123</Password></Database><Server><Port>8080</Port><MaxConnections>100</MaxConnections></Server></Config>
)";
class ConfigParser {
public:struct DBConfig {string host;int port;string username;string password;};struct ServerConfig {int port;int maxConnections;};static pair<DBConfig, ServerConfig> parseConfig(const char* xml) {XMLDocument doc;DBConfig db;ServerConfig server;if (doc.Parse(xml) == XML_SUCCESS) {XMLElement* config = doc.FirstChildElement("Config");// 解析数据库配置XMLElement* dbElem = config->FirstChildElement("Database");db.host = dbElem->FirstChildElement("Host")->GetText();db.port = atoi(dbElem->FirstChildElement("Port")->GetText());db.username = dbElem->FirstChildElement("Username")->GetText();db.password = dbElem->FirstChildElement("Password")->GetText();// 解析服务器配置XMLElement* serverElem = config->FirstChildElement("Server");server.port = atoi(serverElem->FirstChildElement("Port")->GetText());server.maxConnections = atoi(serverElem->FirstChildElement("MaxConnections")->GetText());}return {db, server};}
};

2.元素操作

2.1 FirstChildElement(const char* name = nullptr)

功能:获取元素的第一个子元素。如果 name 参数不为空,则返回名称匹配的第一个子元素。
参数:name 是可选参数,表示子元素的名称。
返回值:指向第一个子元素的指针,如果没有找到返回 nullptr。

XMLElement* firstChild = root->FirstChildElement();
if (firstChild) {std::cout << "First child element: " << firstChild->Name() << std::endl;
}
2.2 NextSiblingElement(const char* name = nullptr)

功能:获取当前元素的下一个同级元素。如果 name 参数不为空,则返回名称匹配的下一个同级元素。
参数:name 是可选参数,表示同级元素的名称。
返回值:指向下一个同级元素的指针,如果没有找到返回 nullptr。

for (XMLElement* child = root->FirstChildElement(); child != nullptr; child = child->NextSiblingElement()) {std::cout << "Sibling element: " << child->Name() << std::endl;
}
2.3 SetName(const char* name)

功能:设置元素的名称。
参数:name 是新名称的字符串。

element->SetName("NewName");
2.4 DeleteChild(XMLElement* child)

功能:删除当前元素的指定子元素。
参数:child 是需要删除的子元素指针。

root->DeleteChild(child);

3. 属性操作

3.1SetAttribute(const char* name, const char* value)

功能:设置元素的字符串属性。
参数:name 是属性名,value 是属性值。

element->SetAttribute("key", "value");
3.2 Attribute(const char* name)

功能:获取元素指定名称的属性值。
参数:name 是属性名。
返回值:指向属性值的字符串指针,如果属性不存在返回 nullptr。

const char* attrValue = element->Attribute("key");
if (attrValue) {std::cout << "Attribute value: " << attrValue << std::endl;
}
3.3 DeleteAttribute(const char* name)

功能:删除元素指定名称的属性。
参数:name 是属性名。

element->DeleteAttribute("key");

4. 文本操作

4.1 SetText(const char* text)

功能:设置元素的文本内容。
参数:text 是字符串,表示要设置的文本内容。

element->SetText("This is text content");
4.2 GetText()

功能:获取元素的文本内容。
返回值:指向文本内容的字符串指针,如果没有文本内容返回 nullptr。

const char* text = element->GetText();
if (text) {std::cout << "Text content: " << text << std::endl;
}

5. 新建元素和节点

5.1 NewElement(const char* name)

功能:创建一个新的元素。
参数:name 是新元素的名称。
返回值:指向新创建的元素的指针。

XMLElement* newElement = doc.NewElement("NewElement");
5.2 InsertFirstChild(XMLNode* child)

功能:将一个子元素插入到当前元素的最前面。
参数:child 是要插入的子元素指针。

root->InsertFirstChild(newElement);
5.3 InsertEndChild(XMLNode* child)

功能:将一个子元素插入到当前元素的末尾。
参数:child 是要插入的子元素指针。

root->InsertEndChild(newElement);

6. 错误处理

6.1 ErrorID()

功能:返回文档的错误代码。

if (doc.ErrorID() != XML_SUCCESS) {std::cerr << "Error occurred: " << doc.ErrorID() << std::endl;
}
6.2ErrorStr()

功能:返回错误信息字符串。

if (doc.ErrorID() != XML_SUCCESS) {std::cerr << "Error details: " << doc.ErrorStr() << std::endl;
}

附录:XML文件格式

  1. XML的基本结构

    • 声明部分
      XML文件的开头是声明,表示XML的版本和编码格式
    <?xml version="1.0" encoding="UTF-8"?>
    • 根元素
      XML文件必须有且只有一个根元素,所有其他内容都嵌套在根元素中
    <root><!-- 子元素 -->
    </root>
    • 元素
      元素是XML的基本组成单位,通常由开始标签和结束标签组成
    <element>内容</element>
    
     - 可以嵌套子元素。- 可以携带属性
    
    <element attribute="value">内容</element>
     - 属性
    

    属性是描述元素的附加信息,格式为key=“value”

    <book id="1" author="Author Name">Book Title</book>
     - 注释
    

    注释用于添加说明性文字

    <!-- 这是一个注释 -->
    
     - 文本内容
    
    <name>张三</name>
  2. XML规则
    - 标签匹配
    标签匹配:每个开始标签必须有对应的结束标签

    <name>张三</name>

    单标签形式需要使用斜杠
    - 区分大小写
    XML区分大小写,例如和是不同的标签。
    - 属性值必须使用引号:可以是单引号或双引号

    <person gender="male"></person>
  3. 转义字符

特殊字符转义符示例代码输出效果
&&amp;<text>AT&amp;T</text><text>AT&T</text>
<&lt;<text>1 &lt; 2</text><text>1 < 2</text>
>&gt;<text>3 &gt; 2</text><text>3 > 2</text>
'&apos;<attribute value='John&apos;s book' /><attribute value='John's book' />
"&quot;<attribute value="He said &quot;Hello&quot;" /><attribute value="He said "Hello"" />

命名空间

  1. 由来
  • XML 中,标签名是自由定义的,不同的 XML 文档中可能会出现相同名称的标签。如果多个 XML 文件需要合并或扩展,很容易发生命名冲突。命名空间为标签和属性分配一个唯一的标识符,解决了冲突问题。
  • 命名空间实际上是一个唯一的 URI(Uniform Resource Identifier),通常是一个 URL(但不需要真实存在)。它标识某一组标签属于特定的上下文。
  1. 语法
  • 默认命名空间
<root xmlns="http://example.com/namespace"><child>Content</child>
</root>
<!--作用范围:没有前缀的所有标签(<root><child>)都属于这个命名空间。-->
  • 带前缀的命名空间
<root xmlns:ns="http://example.com/namespace"><ns:child>Content</ns:child>
</root>
<!--xmlns:ns="http://example.com/namespace" 声明了带前缀的命名空间-->
<!--标签 <ns:child> 使用了 ns 前缀,表示它属于命名空间 http://example.com/namespace-->
<!--作用范围:只有使用了 ns: 前缀的标签。-->
  • 解决的问题
<person xmlns:p="http://example.com/person"><p:name>John</p:name>
</person><product xmlns:prod="http://example.com/product"><prod:name>Smartphone</prod:name>
</product>

模式位置

简单的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- 这是一个简单的 XML 文件,描述书店中的书籍信息 -->
<bookstore><book id="1"><title>XML Basics</title><author>John Doe</author><price currency="USD">29.99</price></book><book id="2"><title>Learning XML</title><author>Jane Smith</author><price currency="EUR">39.99</price></book>
</bookstore>

复杂的XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- 复杂 XML 文件,描述一个电子商务平台的订单信息 -->
<ecommerce xmlns="http://example.com/ecommerce" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/ecommerce ecommerce.xsd"><order id="1001" status="shipped"><customer><name>John Doe</name><email>john.doe@example.com</email><phone>+123456789</phone><address><street>123 Main St</street><city>Springfield</city><state>IL</state><zipcode>62704</zipcode><country>USA</country></address></customer><items><item id="p101"><name>Smartphone</name><quantity>1</quantity><price currency="USD">699.99</price></item><item id="p102"><name>Wireless Headphones</name><quantity>2</quantity><price currency="USD">59.99</price></item></items><payment><method>Credit Card</method><transaction_id>TX123456789</transaction_id><amount currency="USD">819.97</amount></payment><shipping><method>Express</method><tracking_number>EXP123456789</tracking_number><date>2024-11-25</date></shipping></order>
</ecommerce>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/62824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Fastify装饰器:增强你的路由处理功能加入日志

Fastify以其出色的性能和扩展性脱颖而出。装饰器是Fastify提供的一个强大功能&#xff0c;它允许开发者在不修改核心代码的情况下&#xff0c;向请求&#xff08;Request&#xff09;和响应&#xff08;Response&#xff09;对象添加自定义属性和方法。本文将通过一个简单的示例…

redis命令行常用的操作及数据备份

redis命令行常用的操作及数据备份 1.连接命令行2.常用的命令3.数据备份恢复4.桌面管理工具 在日常工作中&#xff0c;有时候会需要去查看redis中某个缓存key是否存在、是否过期等情况&#xff1b;因此&#xff0c;记录整理了一些常用的命令&#xff1b; 1.连接命令行 连接到re…

【大数据学习 | Spark-SQL】关于RDD、DataFrame、Dataset对象

1. 概念&#xff1a; RDD&#xff1a; 弹性分布式数据集&#xff1b; DataFrame&#xff1a; DataFrame是一种以RDD为基础的分布式数据集&#xff0c;类似于传统数据库中的二维表格。带有schema元信息&#xff0c;即DataFrame所表示的二维表数据集的每一列都带有名称和类型…

分布式集群下如何做到唯一序列号

优质博文&#xff1a;IT-BLOG-CN 分布式架构下&#xff0c;生成唯一序列号是设计系统常常会遇到的一个问题。例如&#xff0c;数据库使用分库分表的时候&#xff0c;当分成若干个sharding表后&#xff0c;如何能够快速拿到一个唯一序列号&#xff0c;是经常遇到的问题。实现思…

【算法刷题指南】优先级队列

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

完美解决Python项目中 ReferenceError: weakly-referenced object no longer exists 错误

问题复现 出现 E ReferenceError: weakly-referenced object no longer exists 报错 self <mysql.connector.cursor_cext.CMySQLCursor object at 0x11de2a7d0> operation \n select id, name,occupation,skills \n from resume \n where id %…

C#中的集合初始化器

C#中的集合初始化器是一种简洁的语法&#xff0c;允许在声明集合的同时初始化其元素。这种语法特别适用于初始化实现了IEnumerable接口并具有Add方法的集合类型&#xff0c;如List<T>、Dictionary<TKey, TValue>等。 集合初始化器的基本用法 集合初始化器的基本语…

【Elasticsearch】03-ES RESTFUL使用

1. Mapping操作 # 新增 PUT /hm {"mappings": {"properties": {"info": {"type": "text","analyzer": "ik_smart"},"age": {"type": "byte"},"email": {&quo…

java基础概念46-数据结构1

一、引入 List集合的三种实现类使用了不同的数据结构&#xff01; 二、数据结构的定义 三、常见的数据结构 3-1、栈 特点&#xff1a;先进后出&#xff0c;后进先出。 java内存容器&#xff1a; 3-2、队列 特点&#xff1a;先进先出、后进后出。 栈VS队列-小结 3-3、数组 3-…

第一部分:基础知识 3. 数据类型 --[MySQL轻松入门教程]

第一部分&#xff1a;基础知识 3. 数据类型 --[MySQL轻松入门教程] MySQL 支持多种数据类型&#xff0c;这些数据类型可以分为几大类&#xff1a;数值类型、字符串类型、日期和时间类型、二进制类型以及枚举和集合。每种类型都有其特定的用途和存储需求。以下是 MySQL 中常用的…

Linux的基本操作及虚拟机设置

文章目录 Linux的目录结构Linux中的常见目录 VI和VIM编辑器什么是VI和VIM编辑器VIM的一般模式VIM的编辑模式VIM的命令模式模式间的切换 虚拟机网络配置查看网络信息修改网络配置信息查看和修改主机名服务管理类命令 虚拟机管理操作VMware为虚拟机拍摄快照VMware为虚拟机执行克隆…

【前端】安装hadoop后,前端启动报错,yarn命令

新安装hadoop后&#xff0c;前端启动项目用yarn命令&#xff0c;报错。 报错&#xff1a;系统找不到指定的路径。 No HADOOP_CONF_DIR set. Please specify it either in yarn-env.cmd or in the environment. 解决&#xff1a;删掉hadoop目录下yarn的文件 检查&#xff1a;…

神经网络入门实战:(九)分类问题 → 神经网络模型搭建模版和训练四步曲

(一) 神经网络模型搭建官方文档 每一层基本都有权重和偏置&#xff0c;可以仔细看官方文档。 pytorch 官网的库&#xff1a;torch.nn — PyTorch 2.5 documentation Containers库&#xff1a;用来搭建神经网络框架&#xff08;包含所有的神经网络的框架&#xff09;&#xff1b…

[382]基于springboot的辽B代驾管理系统

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;辽B代驾管理系统 摘 要 使用旧方法对辽B代驾管理系统的信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在辽B代驾管理系统的管理上面可以解决许多信息管理上面的难题&#xff0c;比…

右值引用与临时对象优化总结

右值引用与临时对象优化总结 一、左值与右值的基本概念 左值&#xff08;Lvalue&#xff09;&#xff1a; 有名字、有内存的对象&#xff08;如变量&#xff09;。可被引用&#xff0c;也可被赋值。示例&#xff1a;int a 10; // a 是左值 int& ref a; // 左值引用绑定左…

使用Grafana K6来测测你的系统负载能力

背景 近期我们有个号称会有很高很高并发的系统要上线&#xff0c;为了测试一下自己开发的系统的负载能力&#xff0c;准备了点海克斯科技&#xff0c;来看看抗不抗的住。 之前笔者写过用Apache JMeter进行压力测试的文章&#xff08;传送门&#x1f449;&#xff1a;https://…

Fastadmin的定时任务详解

文章目录 Fastadmin的定时任务详解一、引言二、实现定时任务1、创建定时任务控制器2、配置定时任务 三、使用示例1. 编写备份脚本2. 配置定时任务3. 测试定时任务4. 监控备份结果 四、总结 Fastadmin的定时任务详解 一、引言 FastAdmin是一款基于ThinkPHP框架开发的后台管理系…

xss学习

前言&#xff1a; 每天觉得迷茫的时候为什么不多去看下视频&#xff0c;然后做下笔记啊 我今天开始说明&#xff0c;每天学习都要写一篇毒文章&#xff0c;写博客只为了记录我每天学习的事情&#xff0c;不想每天迷迷糊糊的学了过去了。 回顾&#xff1a; http请求方式&…

华为仓颉编程环境搭建

1、仓颉介绍 摘自华为官方&#xff1a;仓颉编程语言作为一款面向全场景应用开发的现代编程语言&#xff0c;通过现代语言特性的集成、全方位的编译优化和运行时实现、以及开箱即用的 IDE 工具链支持&#xff0c;为开发者打造友好开发体验和卓越程序性能。 其具体特性表现为&am…

QT工程,它该怎么学?

在现代软件开发中&#xff0c;QT因其强大的跨平台能力和友好的用户界面设计工具&#xff0c;成为开发者学习和应用的热门选择。特别是在Linux系统下&#xff0c;如何安装、配置QT开发环境&#xff0c;以及创建和管理QT工程是入门QT开发的关键环节。本文将从安装QT开发环境开始&…