C++ FFLIB之FFXML: 极简化TinyXml 读取
时间:2022-05-03
本文章向大家介绍C++ FFLIB之FFXML: 极简化TinyXml 读取,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
摘要:
XML是结构化的标记语言,经常被用来做配置文件。由于XML的具有非常强的自描述属性,使用XML的配置文件往往直观易懂。C++中解析XML已经有一些非常成熟的类库可以使用,TinyXml是最受欢迎的解析类库之一。尽管TinyXml已经已经封装了解析细节,但是解析、遍历Xml仍然是稍显繁琐。FFXML针对如下需求对TinyXml做了轻量封装:
- 只把XML当成配置文件,也就是说,只有对XML的读取操作,在我日工作中,都是用XML当做纯配置文件,把XML当成序列化文件或数据文件的情况少之又少。
- XML配置文件不会太大,我们假设限制在几千行以内,通常XML配置文件不需要那么大,在这种需求下,的XML的读取效率不是问题,易用性会被放到首位,必须非常容易获取xml中的内容。
- 我们知道XML是结构化的,有层级的概念,这对于C++中的内存模型多多少少会有区别,所以往往获取XML内容的代码会有各种循环、判断、嵌套。FFXML提供了一种“标记语法”使得获取XML内容可以和XML的结构息息对应,即保障了直观,又很容易修改,比如调整了XML的层级关系,FFXML能够保障大多数情况只需改几个字母,而不是修改嵌套的循环代码.
标记语言:
实现先给出示例的XML内容
<game type = "good">
<scene>happly</scene>
<role ID="123456" pos = "any">
<name nick = "xx" >OhNice</name>
<num>99</num>
</role>
</game>
我们知道,如果使用tinyXml读取XML,每一层都需要使用特定的接口获取,从而必须要写一写循环和判断甚至嵌套。FFXML提供了一种“标记语法”来表示XML中各个层级的关系:
- game.scene ffxml通过 “.” 来分割各个层级,game.scene 代表获取root标记下层的scene标记 在FFXML中获取scen标记的值简单到一行代码const char* scene_val = ffxml.get(“game.scene”);
- game.{type} FFXML通过 “{}”表示属性标记,root.{type}表示获取root标记内的type属性的值, 使用FFXML获取type属性的值的代码仍然只有一行:const char* type_val = ffxml.get(“game.{type}”);
- game.@0 获取game标签下的索引0的标签内容,也就是scene的内容,即const char* scene_val = ffxml.get(“game.@0”);
- game.&0 获取game标记下索引0的字标记的name,也就是ffxml.get(“game.&0”) == “scene”;
- game.{@0} 获取game标记下索引0的属性值
- game.{&0} 获取game标记下索引0的属性的name
- FFXML 提供size接口获取字标记的数量如ffxml.size(“game.role”) 表示role标记下字子标记的数量=2
- size 接口也可以获取属性的数量,如ffxml.size(“game.role.{}”) 表示role标记属性的个个数
示例代码:
#include "xml/ffxml.h"
using namespace ff;
int main(int argc, char* argv[])
{
ffxml_t ffxml;
//! 载入test.xml
if (ffxml.load("test.xml"))
{
printf("test.xml 载入失败n");
return 1;
}
printf("获取字段 game.scene: %sn", ffxml.get("game.scene"));
printf("获取字段 game.role.name: %sn", ffxml.get("game.role.name"));
printf("获取字段 game.role.num: %sn", ffxml.get("game.role.num"));
printf("获取属性 game.{type}: %sn", ffxml.get("game.{type}"));
printf("获取属性 game.role.{ID}: %sn", ffxml.get("game.role.{ID}"));
printf("获取标记数量 game: %un", ffxml.size("game"));
printf("获取标记数量 game.role: %un", ffxml.size("game.role"));
printf("获取属性数量 game: %un", ffxml.size("game.{}"));
printf("获取属性数量 game.role: %un", ffxml.size("game.role.{}"));
//! 遍历子节点
char arg_key[128];
char arg_val[128];
for (size_t i = 0; i < ffxml.size("game.role"); ++i)
{
sprintf(arg_key, "game.role.&%u", i);
sprintf(arg_val, "game.role.@%u", i);
printf("遍历子节点 game.role: %s->%sn", ffxml.get(arg_key), ffxml.get(arg_val));
}
//! 遍历属性节点
for (size_t i = 0; i < ffxml.size("game.role"); ++i)
{
sprintf(arg_key, "game.role.{&%u}", i);
sprintf(arg_val, "game.role.{@%u}", i);
printf("遍历属性 game.role: %s->%sn", ffxml.get(arg_key), ffxml.get(arg_val));
}
printf("组合 game.role.@1.{@nick} %sn", ffxml.get("game.role.@0.{@nick}"));
return 0;
}
总结:
详细源代码:https://github.com/fanchy/fflib
- 巨头们关注的实时Web:发展与相关技术
- 碎片化 | 第四阶段-54-hibernate-spring整合流程-视频
- OpenDaylight Lithium版本简单应用及流表操作指南
- 碎片化 | 第四阶段-55-OpenSessionInViewFilter组件配置解决session问题-视频
- 入门Webpack(上)
- 碎片化 | 第四阶段-56-ManyToOne和OneToMany映射关系-视频
- 基于网络流量的SDN最短路径转发应用
- 碎片化 | 第四阶段-57-hibernate二级缓存-视频
- NoSQL篇 | NoSQL从小白到码神 之 Redis篇
- Neutron和ONOS集成实践
- 基于OpenDaylight和OVSDB搭建VxLAN网络
- 史上最强----机器学习经典总结---入门必读
- SDNLAB群分享(四):利用ODL下发流表创建VxLAN网络
- Neutron集成ONOS源码分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- python opencv实现图片缺陷检测(讲解直方图以及相关系数对比法)
- Js 的事件循环(Event Loop)机制以及实例讲解
- 你不知道的js中关于this绑定机制的解析[看完还不懂算我输]
- 解决Django部署设置Debug=False时xadmin后台管理系统样式丢失
- 算法-查找斐波纳契数列中第 N 个数
- 在python中修改.properties文件的操作
- Django Xadmin多对多字段过滤实例
- 算法-姓名去重
- Ubuntu18.04安装 PyCharm并使用 Anaconda 管理的Python环境
- Python Opencv中用compareHist函数进行直方图比较对比图片
- 面试题-树状数组结构转化
- Xadmin+rules实现多选行权限方式(级联效果)
- Android仿主流壁纸App设置界面
- Android中WindowManager与WMS的解析
- 算法(简单)_搜索二维矩阵&分解质因数