Boost读写xml

Boost读写xml

文章目录

  • Boost读写xml
    • 写在前面
    • 准备工作
    • 简单读写
      • 写xml
      • 读xml
        • 键值查找
        • 遍历
      • 设置默认值
      • 异常处理
    • 具有属性的xml
      • 写xml
      • 读xml
        • 键值查找
        • 遍历
    • 知识补充

写在前面

​ 前面我们讲过了如何使用Boost读写ini文件,这一篇我们将介绍如何用Boost读写xml文件。

​ XML (Extensible Markup Language) 是一种通用的数据描述语言,它提供了一种独立于平台和编程语言的方式来存储和交换结构化数据。XML 文件采用标签的形式描述数据,使得数据具有自我描述的特点,更易于理解和管理。XML 广泛应用于各种领域,如 Web 开发、配置管理、数据交换等,它支持数据验证、数据转换等功能,并提供了丰富的编程接口,方便开发人员在应用程序中解析和操作 XML 数据。

  • 测试环境:Win11 + Vs2015 + Boost1.80
  • 这里默认读者已经安装好Boost库,不知道如何安装可查看Boost编译使用_boost 编译 使用

准备工作

  • 需要用到的头文件
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>

简单读写

  • Boost中读写xmlini文件都是使用property_tree来完成的,所以大部分东西是通用的。
  • 需要注意的是ini文件没有节点嵌套,所有节点都在根节点下的一级节点,xml是有多级节点的,且允许多级嵌套,但根节点只有一个。
  • 下面将展示简单的xml文件的读写功能,进阶用法请看具有属性的xml

写xml

void write_xml_file_test() {using	boost::property_tree::ptree;ptree root;	// 创建根节点ptree student_pt;student_pt.put<std::string > ("Name", "Xiao Ming");student_pt.put<uint8_t>("Age", 15);student_pt.put<std::string>("Sex", "man");student_pt.put<uint8_t>("Class", 1);root.add_child("XmlTest.Student", student_pt);	// 将子节点添加到根节点中// 添加setting 确保输出文件内容有缩进auto setting = boost::property_tree::xml_writer_make_settings<std::string>('\t', 1);write_xml("example2.xml", root, std::locale(), setting);
}
<?xml version="1.0" encoding="utf-8"?>
<XmlTest><Student><Name>Xiao Ming</Name><Age>15</Age><Sex>man</Sex><Class>1</Class></Student>
</XmlTest>

读xml

键值查找
void read_xml_from_key(std::string fileName) {using	boost::property_tree::ptree;ptree root;read_xml(fileName, root);// 这里的root是根节点,想要直接访问元素,需要全名称描述(XmlTest.Student.Name)// 键值查找,如果键不存在,则触发异常std::string st_name = root.get<std::string>("XmlTest.Student.Name");	int st_age = root.get<int>("XmlTest.Student.Age");std::string st_sex = root.get<std::string>("XmlTest.Student.Sex");int st_class = root.get<int>("XmlTest.Student.Class");std::cout << "Name: " << st_name << std::endl;std::cout << "Age: " << st_age << std::endl;std::cout << "Sex: " << st_sex << std::endl;std::cout << "Class: " << st_class << std::endl;// student_node节点下是Student的元素,可直接获取(Name)ptree student_node = root.get_child("XmlTest.Student");  // 获取 Student 子节点st_name = student_node.get<std::string>("Name");std::cout << "Name: " << st_name << std::endl;
}/* output:
Name: Xiao Ming
Age: 15
Sex: man
Class: 1
Name: Xiao Ming
*/
遍历
void read_xml_file_text(std::string fileName) {using	boost::property_tree::ptree;ptree root;read_xml(fileName, root);ptree student_node(root.get_child("XmlTest.Student"));	// 获取 Student 子节点// 遍历子节点std::cout << "method 1:\n";for (ptree::iterator it = student_node.begin(); it != student_node.end(); ++it) {std::cout << "\t" << it->first;std::cout << ":" << it->second.data() << std::endl;}std::cout << "method 2:\n";for (const auto &t : student_node) {std::cout << "\t" << t.first;std::cout << ":" << t.second.data() << std::endl;}
}/* output:
method 1:Name:Xiao MingAge:15Sex:manClass:1
method 2:Name:Xiao MingAge:15Sex:manClass:1
*/

设置默认值

  • property_tree设置默认的方式是一样的,我们在Boost读写ini文件中已经说明过了。

    // 获取当前节点不存在的节点时,无默认值,引发程序异常
    int st_heigh = student_node.get<int>("Height");
    // 获取当前节点不存在的节点时,有默认值,不会引发异常
    int st_heigh = student_node.get<int>("Height"175);
    

异常处理

  • 读写xml异常一般有以下几种:

    • 读取文件不存在
    • 读取节点、属性等不存在
    • 属性内容转换失败
  • 最简单的方式是使用 std::exception 捕获所有的异常,但不利于异常分开处理

try{...    int st_heigh = student_node.get<int>("Height"); // 引发异常...    
}
catch (const boost::property_tree::ptree_bad_path& e) {			//无法访问节点异常std::cerr << "Node access error: " << e.what() << std::endl;
}
catch (const boost::property_tree::xml_parser_error& e) {		// 语法错误异常std::cerr << "XML parsing error: " << e.what() << std::endl;
}
catch (std::exception &e) {	std::cerr << e.what() << "\n";
}
/* output:
No such node (Height)
*/

具有属性的xml

  • xml文件除了多级节点外,每个节点、元素都可以设置属性值,类似于以下这种,一个元素可有多个属性。

    <Name type="string">Xiao xiao</Name>
    
  • 属性值必须被引号包围,单双引号都可,更多详细的关于xml的文件格式可参考知识补充

写xml

void write_xml_has_property(std::string fileName) {using	boost::property_tree::ptree;ptree root;// 创建Student 子节点ptree student_node;student_node.put<std::string>("Name", "Xiao xiao");student_node.put("Name.<xmlattr>.type", "string");student_node.put<int>("Age",  16);student_node.put("Age.<xmlattr>.type", "int");student_node.put<std::string>("Sex", "man");student_node.put("Sex.<xmlattr>.type", "string");student_node.put<int>("Class", 1);student_node.put("Class.<xmlattr>.type", "int");root.add_child("XmlTest.Student",student_node);auto setting = boost::property_tree::xml_writer_make_settings<std::string>('\t', 1);write_xml(fileName, root, std::locale(), setting);
}
<?xml version="1.0" encoding="utf-8"?>
<XmlTest><Student><Name type="string">Xiao xiao</Name><Age type="int">16</Age><Sex type="string">man</Sex><Class type="int">1</Class></Student>
</XmlTest>

读xml

键值查找
void read_xml_has_property(std::string fileName) {try {using	boost::property_tree::ptree;ptree root_node;read_xml(fileName, root_node);ptree student_node(root_node.get_child("XmlTest.Student"));std::string st_name = student_node.get<std::string>("Name");std::string st_name_type = student_node.get<std::string>("Name.<xmlattr>.type");int st_age = student_node.get<int>("Age");std::string st_age_type = student_node.get<std::string>("Age.<xmlattr>.type");std::string st_sex = student_node.get<std::string>("Sex");std::string st_sex_type = student_node.get<std::string>("Sex.<xmlattr>.type");int st_class = student_node.get<int>("Class");std::string st_class_type = student_node.get<std::string>("Class.<xmlattr>.type");std::cout << "Name: "<<st_name_type<<" "<< st_name << std::endl;std::cout << "Age: " << st_age_type << " " << st_age << std::endl;std::cout << "Sex: " << st_sex_type << " " << st_sex << std::endl;std::cout << "Class: " << st_class_type << " " << st_class << std::endl;}catch (std::exception &e) {std::cerr << e.what() << "\n";}
}/* output:
Name: string Xiao xiao
Age: int 16
Sex: string man
Class: int 1
*/
遍历
void read_xml_has_property2(std::string fileName) {try {using	boost::property_tree::ptree;ptree root_node;read_xml(fileName, root_node);ptree student_node(root_node.get_child("XmlTest.Student"));// 遍历 Student节点和属性for (const auto &t : student_node) {std::cout << t.first << ": " <<t.second.get<std::string >("<xmlattr>.type") << " "<<t.second.data() << "\n";}}catch (std::exception &e) {std::cerr << e.what() << "\n";}
}/* output:
Name: string Xiao xiao
Age: int 16
Sex: string man
Class: int 1
*/

知识补充

  • 这里对xml语法进行一个简要介绍

  • xml文件语法类似于HTML文件格式通过标签表示节点或者元素。

    <a>name</a>
    
  • 允许多层嵌套,可设置属性对元素进行描述。

  • 更多详细可参考网络上的xml文件格式等。

  • XML 语法

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

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

相关文章

C++入门系列-类对象模型this指针

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 类对象模型 如何计算类对象的大小 class A { public:void printA(){cout << _a << endl;} private:char _a; }; 算算看&#xff0c;这个类的大小是多少 我们知道…

掌握JavaScript面向对象编程核心密码:深入解析JavaScript面向对象机制对象概念、原型模式与继承策略全面指南,高效创建高质量、可维护代码

ECMAScript&#xff08;简称ES&#xff0c;是JavaScript的标准规范&#xff09;支持面向对象编程&#xff0c;通过构造函数模拟类&#xff0c;原型链实现继承&#xff0c;以及ES6引入的class语法糖简化面向对象开发。对象可通过构造函数创建&#xff0c;使用原型链共享方法和属…

从0开始linux(1)——文件操作

欢迎来到博主的专栏——从0开始linux 博主ID&#xff1a;代码小豪 博主使用的linux发行版是&#xff1a;CentOS 7.6 不同版本下的操作可能存在差异 文章目录 命令文件操作命令文件树和文件路径文件树绝对路径相对路径 文件属性tree指令删除文件复制文件 大家还记得在小学第一次…

Amazon EKS创建EBS的存储类

1、创建 Amazon EBS CSI 驱动程序 IAM 角色 相关文档 先决条件&#xff0c;是否有 IAM OIDC 提供商&#xff0c;详情 IAM OIDC 提供商创建文档 IAM OIDC 提供商id 在 Select trusted entity&#xff08;选择受信任的实体&#xff09;页面上操作&#xff0c;最后点击下一步 在…

代码随想录算法训练营第25天 | 216.组合总和III、17.电话号码的字母组合

代码随想录算法训练营第25天 | 216.组合总和III、17.电话号码的字母组合 自己看到题目的第一想法看完代码随想录之后的想法 链接: 216.组合总和III 链接: 17.电话号码的字母组合 自己看到题目的第一想法 216.组合总和III&#xff1a;递归函数终止条件为搜索得到的数相加为n&…

Rust 和 Go 哪个更好?

在讨论 Rust 与 Go 两种编程语言哪种更优秀时&#xff0c;我们将探讨它们在性能、简易性、安全性、功能、规模和并发处理等方面的比较。同时&#xff0c;我们看看它们有什么共同点和根本的差异。现在就来看看这个友好而公平的对比。 Rust 和 Go 都是优秀的选择 首先&#xff…

OD试题(11)

文章目录 1.自守数2.等差数列3.输入整形数组和排序标识&#xff0c;对其元素按照升序或降序4. 字符统计5.记负均正II 1.自守数 描述&#xff1a;自守数是指一个数的平方的尾数等于该数自身的自然数。例如&#xff1a;25^2 625&#xff0c;76^2 5776&#xff0c;9376^2 8790…

ssh远程访问windows系统下的jupyterlab

网上配置这一堆那一堆&#xff0c;特别乱&#xff0c;找了好久整理后发在这里 由于既想打游戏又想做深度学习&#xff0c;不舍得显卡性能白白消耗&#xff0c;这里尝试使用笔记本连接主机 OpenSSH 最初是为 Linux 系统开发的&#xff0c;现在也支持包括 Windows 和 macOS 在内…

【JAVA项目】基于SSM的【寝室管理系统设计】

技术简介&#xff1a;采用B/S架构、ssm 框架和 java 开发的 Web 框架&#xff0c; eclipse开发工具。 系统简介&#xff1a;寝室管理设计的主要使用者分为管理员、宿舍长和学生&#xff0c;实现功能包括管理员权限&#xff1a;首页、个人中心、学生管理、宿舍号管理、宿舍长管理…

链舞算法谱---链表经典题剖析

前言&#xff1a;探究链表算法的奥秘&#xff0c;解锁编程新世界&#xff01; 欢迎来到我的链表算法博客&#xff0c;这将是您深入了解链表算法&#xff0c;提升编程技能的绝佳机会。链表作为数据结构的重要成员之一&#xff0c;其动态性和灵活性在实现某些功能上发挥不可替代的…

生成树协议(STP,MSTP,RSTP)详解

目录 STP生成树协议 二层环路出现的原因&#xff1a; 二层环路引发的危害&#xff1a; stp生成树防环的基本思路&#xff1a; 802.1D生成树协议&#xff1a; 配置BPDU的报文结构&#xff1a; 配置BPDU中某些字段的解析&#xff1a; TCN BPDU报文格式&#xff1a; stp中…

Java中接口的默认方法

为什么要使用默认方法 当我们把一个程序的接口写完后 用其他的类去实现&#xff0c;此时如果程序需要再添加一个抽象方法的时候我们只有两种选择 将抽象方法写在原本的接口中 但是这样写会导致其他所有改接口的实现类都需要实现这个抽象方法比较麻烦 写另一个接口 让需要的实…

程序的机器级表示——Intel x86 汇编讲解

往期地址&#xff1a; 操作系统系列一 —— 操作系统概述操作系统系列二 —— 进程操作系统系列三 —— 编译与链接关系操作系统系列四 —— 栈与函数调用关系操作系统系列五 —— 目标文件详解操作系统系列六 —— 详细解释【静态链接】操作系统系列七 —— 装载操作系统系列…

VBA 拆分Excel中的各sheet为文件

一. 方式1 xlOpenXMLWorkbook&#xff1a;.xlsx格式的文件xlWorkbookDefault&#xff1a;当前Excel的格式(当前Excel是什么格式&#xff0c;被拆分出的sheet页所生成的文件就是什么格式)"\"&#xff1a;可以使用Application.PathSeparator代替 Sub 拆分工作表() 初…

基于肤色模型的人脸识别FPGA实现,包含tb测试文件和MATLAB辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 matlab2022a的测试结果如下&#xff1a; vivado2019.2的仿真结果如下&#xff1a; 将数据导入到matlab中&#xff0c; 系统的RTL结构图如下图所示…

多态的原理

前言:以下的内容均是在VS2019的环境中&#xff0c;32位平台下的 目录 1.多态的实现条件 虚函数重写的两个例外 一个题加深理解 总结 重载 重写 重定义区别 2.多态的实现原理 单继承 多继承 动态多态和静态多态 多态的好问题 1.多态的实现条件 虚函数&#xff1a;被…

leetcode40-Combination Sum II

题目 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意&#xff1a;解集不能包含重复的组合。 示例 1: 输入: candidates [10,1,2,7,…

大模型日报2024-05-04

大模型日报 2024-05-04 大模型资讯 谷歌发布全新语言模型 GPT-Next 摘要: 谷歌推出了其新一代语言模型 GPT-Next&#xff0c;该模型在多个自然语言处理任务上取得了显著的进步。 百度推出大型语言模型 Baidu LM 2.0 摘要: 百度发布了升级版的大型语言模型 Baidu LM 2.0&#xf…

使用Ruoyi的定时任务组件结合XxlCrawler进行数据增量同步实战-以中国地震台网为例

目录 前言 一、数据增量更新机制 1、全量更新机制 2、增量更新机制 二、功能时序图设计 1、原始请求分析 2、业务时序图 三、后台定时任务的设计与实现 四、Ruoyi自动任务配置 1、Ruoyi自动任务配置 2、任务调度 总结 前言 在之前的相关文章中&#xff0c;发表文章列…

2024年 Java 面试八股文——SpringBoot篇

目录 1. 什么是 Spring Boot&#xff1f; 2. 为什么要用SpringBoot 3. SpringBoot与SpringCloud 区别 4. Spring Boot 有哪些优点&#xff1f; 5. Spring Boot 的核心注解是哪个&#xff1f;它主要由哪几个注解组成的&#xff1f; 6. Spring Boot 支持哪些日志框架&#…