tinyxml源码解析(上)
转载于:http://www.cnblogs.com/marchtea/archive/2012/11/09/2762669.html
前言:
前段时间做功能可行性的时候简单的使用了tinyxml。在sourceforge下载的时候,看到老外对于这个库的评价很高,因此就有冲动进行学习这么一个优秀的框架。简单查看了代码,代码量也不是很大。刚好事情做的差不多,索性就学习学习好了。第一次尝试阅读正式的框架,水平也不是很好,可能多少会有点出错,要是有错误还望多包涵并且提出来,一起进步哈。
文章打算分为三部分,第一部分介绍了TiXmlBase,TiXmlNode这两个基类,第二部分详细了介绍了代表节点的几个类,第三部分介绍了库中提供的一些工具类。
正言:
先简单介绍下tinyxml吧。在我的前一篇文章也介绍了下,还有使用方法。tinyxml是一款轻量级的xml parser。其目的在于在提供基本的xml操作的同时保持一个简单的用户接口供用户使用。其能实现基本的xml的特性。如遍历xml文件,获取节点等。至于dtd,xstl等特性并不支持。详细可以查看我的上一篇文章。
tinyxml整体的类的架构图如下:

TiXmlBase是所有tinyxml里面的元素的基类,其提供了一些基本的操作和属性。一会分析。
xml中的节点的所有父类皆为TiXmlNode,其可以转化成任意一种特定的节点。而对于我们的element节点中的属性来说,其在构造时也是做为element的子节点来构建的,不过由于其只能出现在element中,因此并没有继承自TiXmlNode。
TiXmlNode也提供了一些基本的节点操作,如获取子节点,插入子节点等。
这篇文章将主要讲解TiXmlBase以及TiXmlNode。
TiXmlBase:
先讲下所有类的基类TiXmlBase吧。
这里是头文件的内容。
读完头文件,来看看具体的实现
首先是之前提到的entity,定义在tinyxmlparser.cpp

//定义了xml中的entity数组.用于函数转化
TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
{
{ "&", 5, '&' },
{ "<", 4, '<' },
{ ">", 4, '>' },
{ """, 6, '\"' },
{ "'", 6, '\'' }
};

接下来就是说到的EncodeString了.
SkipWhiteSpace:这个实在没什么好说的.

1 //折叠又打不开了.就不折叠了
2 const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
3 {
4 if ( !p || !*p )
5 {
6 return 0;
7 }
8 if ( encoding == TIXML_ENCODING_UTF8 )
9 {
10 while ( *p )
11 {
12 const unsigned char* pU = (const unsigned char*)p;
13
14 // 跳过ms的UTF8头
15 if ( *(pU+0)==TIXML_UTF_LEAD_0
16 && *(pU+1)==TIXML_UTF_LEAD_1
17 && *(pU+2)==TIXML_UTF_LEAD_2 )
18 {
19 p += 3;
20 continue;
21 }
22 else if(*(pU+0)==TIXML_UTF_LEAD_0
23 && *(pU+1)==0xbfU
24 && *(pU+2)==0xbeU )
25 {
26 p += 3;
27 continue;
28 }
29 else if(*(pU+0)==TIXML_UTF_LEAD_0
30 && *(pU+1)==0xbfU
31 && *(pU+2)==0xbfU )
32 {
33 p += 3;
34 continue;
35 }
36
37 //仍然采用了英文的,ansi的方式进行判断.
38 if ( IsWhiteSpace( *p ) )
39 ++p;
40 else
41 break;
42 }
43 }
44 else
45 {
46 //对于其他编码也是
47 while ( *p && IsWhiteSpace( *p ) )
48 ++p;
49 }
50
51 return p;
52 }

ReadName
ReadText: 读取属性中的值,读取<></>之间的文本.
StringEqual:就是一个比较函数,比较简单.
ConvertUTF32ToUTF8:这是个转化工具,我也不大懂.根据编码规则应该就能实现.贴出来吧.
看完了最基础的TiXmlBase类之后,也能感觉到,这个基类就是提供了基本的处理工具的作用,以及为后续的类设定了一些虚函数供后续继承.而且由于是纯虚类,因此也不能声明TiXmlBase的对象.
接下来就看看还具有一定实用性的TiXmlNode类吧.
这个类是除了TiXmlAttribute之外的所有元素类的父类,里面提供了对于xml对象基本的操作.如遍历子节点,访问兄弟节点,插入,删除节点等操作.这样在后面的子类继承时,就不用考虑这些操作了.
先看看头文件吧.
在头文件中,我们可以看到,TiXmlNode提供了很多遍历,查找子节点的函数.为后续继承的子类搭好了树结构的基础.同时通过私有化复制构造函数以及复制操作符的方式避免意外的复制从而导致错误以及额外的开销.
来看具体的实现.我们就挑几个重要的函数看看好了.
首先是遍历子节点的操作IterateChildren
至于带value版本的IterateChildren,也调用了其他的函数
而带value版本的FirstChild其实也没什么神秘的,就是对链表的操作而已.
那那些NextSibling等等其实也没有什么好深究的了.还是看看变动性操作吧.
LinkEndChild
分析之后可以看出整体采用的就是双向链表来组织数据的.其他的代码就不用怎么展示了,大多都是链表的操作.
总结:
第一节主要就介绍两个基类及其成员函数.整体显得会比较枯燥,而且看完还是不明白整体tinyxml的处理方式.
详细的tinyxml处理流程我将在第二节进行说明.有什么疑问欢迎交流.第一次写这样的文章,写得不是很好,望大家多包涵.
tinyxml源码解析(上)的更多相关文章
- tinyxml源码解析(中)
转载于:http://www.cnblogs.com/marchtea/archive/2012/11/20/2766756.html 前言: 之前趁着这段时间比较空闲,也因为听闻tinyxml大名, ...
- Laravel学习笔记之Session源码解析(上)
说明:本文主要通过学习Laravel的session源码学习Laravel是如何设计session的,将自己的学习心得分享出来,希望对别人有所帮助.Laravel在web middleware中定义了 ...
- spring源码解析--上
本文是作者原创,版权归作者所有.若要转载,请注明出处. 首先是配置类 package com.lusai.config; import org.springframework.context.anno ...
- FMDB源码解析(上)-FMDB基本使用
目录 一: 初识FMDB 二: 基本使用 三: 基本操作 结束 最后更新:2017-02-22 2017, 说到做到 一: 初识FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的 ...
- Kakfa揭秘 Day9 KafkaReceiver源码解析
Kakfa揭秘 Day9 KafkaReceiver源码解析 上一节课中,谈了Direct的方式来访问kafka的Broker,今天主要来谈一下,另一种方式,也就是KafkaReceiver. 初始化 ...
- Spring源码解析系列汇总
相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...
- 深入springMVC源码------文件上传源码解析(下篇)
在上篇<深入springMVC------文件上传源码解析(上篇) >中,介绍了springmvc文件上传相关.那么本篇呢,将进一步介绍springmvc 上传文件的效率问题. 相信大部分 ...
- TiKV 源码解析系列文章(三)Prometheus(上)
本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...
- Retrofit源码解析(上)
简介Retrofit是Square公司开发的一款针对Android网络请求的框架,官网地址http://square.github.io/retrofit/ ,在官网上有这样的一句话介绍retrofi ...
随机推荐
- C if语句判断年龄
#include <stdio.h> int main(int argc, char **argv) { //新建两个变量给变量赋值跟初始化:const int a=45;int c=0; ...
- STM32F4 编程手册学习1_编程模型
STM32F4 programming manual_1 1. 处理器模式与特权等级 处理器模式分为以下两种: 线程模式: 用来执行应用软件: 处理器从reset出来时,进入线程模式: CONTROL ...
- Mysql-表和字段操作
1.查看表 show tables; 2.创建表 create table test( id int primary key auto_increment, name varchar(40) not ...
- hadoop问题集(1)
参考: http://dataunion.org/22887.html 1.mapreduce_shuffle does not exist 执行任何时报错: Container launch ...
- JavaScript闭包总结
闭包是你家庭中的第三者你在享受着第三者给你带来的便利时,而你的家庭也随时触发前所未有的危机(直男癌患者的观点);闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部 ...
- Java学习个人备忘录之关键字final
final关键字final可以修饰类,方法,变量.final修饰的类不可以被继承final修饰的方法不可以被覆盖final修饰的变量是一个常量.只能被赋值一次.内部类只能访问被final修饰的局部变量 ...
- 系统常量对话框QT实现
1.运行结果: 2.代码 main.cpp #include "constantdiag.h" #include <QtWidgets/QApplication> in ...
- 2019寒假训练营寒假作业(二) MOOC的网络空间安全概论笔记部分
视频课程--MOOC的网络空间安全概论笔记 第一章 网络空间安全概述 2001年,网络空间概念被首次提出: 网络空间安全框架: 1.设备层安全: 可通过截获电磁辐射获取计算机信息.通过硬件木马(恶意电 ...
- Ligerui首页的快速搭建
一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 3.Ligerui首页的快速搭建 4.Ligerui Grid组件--学生信 ...
- OSG配置捷径,VS2013+WIN10
在自己电脑上用CMAKE已经编译好了,上传到百度云里面了. 环境是WIN10+VS2013. 链接:http://pan.baidu.com/s/1hrO7GFE 密码:fwkw 解压之后放在C盘或者 ...