转载于: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, '&' },
{ "&lt;", 4, '<' },
{ "&gt;", 4, '>' },
{ "&quot;", 6, '\"' },
{ "&apos;", 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源码解析(上)的更多相关文章

  1. tinyxml源码解析(中)

    转载于:http://www.cnblogs.com/marchtea/archive/2012/11/20/2766756.html 前言: 之前趁着这段时间比较空闲,也因为听闻tinyxml大名, ...

  2. Laravel学习笔记之Session源码解析(上)

    说明:本文主要通过学习Laravel的session源码学习Laravel是如何设计session的,将自己的学习心得分享出来,希望对别人有所帮助.Laravel在web middleware中定义了 ...

  3. spring源码解析--上

    本文是作者原创,版权归作者所有.若要转载,请注明出处. 首先是配置类 package com.lusai.config; import org.springframework.context.anno ...

  4. FMDB源码解析(上)-FMDB基本使用

    目录 一: 初识FMDB 二: 基本使用 三: 基本操作 结束 最后更新:2017-02-22 2017, 说到做到 一: 初识FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的 ...

  5. Kakfa揭秘 Day9 KafkaReceiver源码解析

    Kakfa揭秘 Day9 KafkaReceiver源码解析 上一节课中,谈了Direct的方式来访问kafka的Broker,今天主要来谈一下,另一种方式,也就是KafkaReceiver. 初始化 ...

  6. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  7. 深入springMVC源码------文件上传源码解析(下篇)

    在上篇<深入springMVC------文件上传源码解析(上篇) >中,介绍了springmvc文件上传相关.那么本篇呢,将进一步介绍springmvc 上传文件的效率问题. 相信大部分 ...

  8. TiKV 源码解析系列文章(三)Prometheus(上)

    本文为 TiKV 源码解析系列的第三篇,继续为大家介绍 TiKV 依赖的周边库 rust-prometheus,本篇主要介绍基础知识以及最基本的几个指标的内部工作机制,下篇会介绍一些高级功能的实现原理 ...

  9. Retrofit源码解析(上)

    简介Retrofit是Square公司开发的一款针对Android网络请求的框架,官网地址http://square.github.io/retrofit/ ,在官网上有这样的一句话介绍retrofi ...

随机推荐

  1. Java程序员自我介绍

    有关Java程序员的面试自我介绍范文(一) 我叫XXX,今年21岁,毕业于XX解放军信息工程大学计算机科学与技术专业,拥有扎实的Core Java基础,良好的编程风格;熟悉JSP+Servlet+Ja ...

  2. array.some() 方法兼容ie8

    在第 5 版时,some 被添加进 ECMA-262 标准:这样导致某些实现环境可能不支持它.你可以把下面的代码插入到脚本的开头来解决此问题,从而允许在那些没有原生支持它的实现环境中使用它.该算法是  ...

  3. js经典试题之常用的方法

    js经典试题之常用的方法 1.下面代码输出的值 let s = "bob" const replaced = s.replace('b', 'l') replaced === &q ...

  4. LVS+Keepalive+Nginx实现负载均衡

    本文参考:http://blog.csdn.net/yinwenjie/article/details/47211551 简单粗暴写一下,做备忘,刚刚搭好没做优化呢,后期补充 一.机器准备 LVS-M ...

  5. scanf格式控制符的完整格式

    scanf格式控制的完整格式: %     *     m     l或h     格式字符 ①格式字符与printf函数中的使用方式相同,以%d.%o.%x.%c.%s.%f.%e,无%u格式.%g ...

  6. activiti工作流已办和待办查询sql

    最近项目中遇到一个问题,需要activiti的工作流表和业务表关联分页查询,然而我对于工作流的查询并不太熟悉,所以学习并总结如下. 想看看activiti到底怎么查询的待认领和待办.已办的查询sql, ...

  7. 有关c#的学习笔记整理与心得

    [ 塔 · 第 一 条 约 定 ] 整理c#:Array Arraylist List Hashtable Dictionary Stack Queue等 Array 的容量是固定的,而 ArrayL ...

  8. Debian实验机 常用命令

    1.开启中文输入法 fcitx 2. 开启无线连接 wicd 3. 远程连接 ssh root@XXX.XXX.XXX.XXX 4. 启动Ulipad ~/ulipad-master# python ...

  9. Spring Boot(四)@EnableXXX注解分析

    在学习使用springboot过程中,我们经常碰到以@Enable开头的注解,其实早在Spring3中就已经出现了类似注解,比如@EnableTransactionManagement.@ Enabl ...

  10. 3DMAX2016破解教程

    首先,断网. 然后,下载3DMAX2016注册机. 然后,打开已经安装的3DMAX2016,会出现下图,点击激活按钮. 之后,以管理员身份打开3DMAX2016注册机,把申请号复制到注册机里面的请求码 ...