Boost读写xml

news/2024/10/19 3:25:46/
xmlns="http://www.w3.org/2000/svg" style="display: none;">

xml_0">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_27">写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"><?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_62">读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_175">具有属性的xml

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

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

xml_185">写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"><?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_222">读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文件格式通过标签表示节点或者元素。

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

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

  • XML 语法


http://www.ppmy.cn/news/1448973.html

相关文章

互联网医院系统源码开发实战教学:搭建在线问诊APP

今天&#xff0c;笔者将带领大家进行一次互联网医院系统源码开发的实战教学&#xff0c;让我们一起来探索搭建一个高效便捷的在线问诊平台。 一、需求分析和功能设计 在开始源码开发之前&#xff0c;我们首先需要进行需求分析和功能设计。一般来说&#xff0c;一个完善的在线…

【Flutter】极光推送配置流程(小米厂商通道) 章二

前言 继【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 并且&#xff0c;我大概率不会去修改第一篇文章的内容。 随着我自己在配置公司的项目的同时&#xff0c;我希望一直更新这个推送系列文章。 在章一配置完后&#xff0c;也是出现了一些问题&#xff0c;所以本…

Acwing 818. 数组排序

给定一个长度为 n n n的数组 a a a以及两个整数 l l l和 r r r&#xff0c;请你编写一个函数&#xff0c;void sort(int a[], int l, int r)&#xff0c;将 a [ l ] ∼ a [ r ] a[l]∼a[r] a[l]∼a[r]从小到大排序。 输出排好序的数组 a。 输入格式 第一行包含三个整数 n &…

全网最强JavaWeb笔记 | 万字长文爆肝JavaWeb开发——day09Mybatis

万字长文爆肝黑马程序员2023最新版JavaWeb教程。这套教程打破常规&#xff0c;不再局限于过时的老套JavaWeb技术&#xff0c;而是与时俱进&#xff0c;运用的都是企业中流行的前沿技术。笔者认真跟着这个教程&#xff0c;再一次认真学习一遍JavaWeb教程&#xff0c;温故而知新&…

XML:简介

一、何为XML XML 指可扩展标记语言&#xff08;EXtensible Markup Language&#xff09;&#xff0c;设计宗旨是传输数据&#xff0c;而非显示数据&#xff0c;其是W3C&#xff08;指万维网联盟&#xff08;World Wide Web Consortium&#xff09;&#xff09;的推荐标准。 实例…

MATLAB初学者入门(21)—— 霍夫曼树

霍夫曼编码是一种广泛用于数据压缩的有效技术。它基于字符频率或概率来构造最优的前缀码&#xff0c;使得常用字符的编码长度较短&#xff0c;不常用的字符编码长度较长&#xff0c;从而达到压缩数据的目的。MATLAB中可以通过一系列步骤来实现霍夫曼树的构建和相应的编码过程。…

容器安全-镜像扫描

前言 容器镜像安全是云原生应用交付安全的重要一环&#xff0c;对上传的容器镜像进行及时安全扫描&#xff0c;并基于扫描结果选择阻断应用部署&#xff0c;可有效降低生产环境漏洞风险。容器安全面临的风险有&#xff1a;镜像风险、镜像仓库风险、编排工具风险&#xff0c;小…

使用Python及R语言绘制简易数据分析报告

Pytohn实现 在python中有很多包可以实现绘制数据分析报告的功能&#xff0c;推荐两个较为方便的包&#xff1a;pandas-profiling 和 sweetviz 。 使用 pandas-profiling 包&#xff08;功能全面&#xff09; 这个包的个别依赖包与机器学习的 sklearn 包的依赖包存在版本冲突&a…