zoukankan      html  css  js  c++  java
  • tinyxml源码解析(中)

    转载于:http://www.cnblogs.com/marchtea/archive/2012/11/20/2766756.html

    前言:

      之前趁着这段时间比较空闲,也因为听闻tinyxml大名,因此就阅读了tinyxml的源码.在上一篇博文中<tinyxml源码解析(上)>中对tinyxml整体架构以及其中两个基类TiXmlBase,TiXmlNode进行了注释解析.不过文章写得有点啰嗦,太过详细.因此这篇文章将提取其中的部分设计而不是对于每个函数进行注释.

      本文将主要介绍tinyxml对于attribute的处理,各个元素类的简单介绍以及tinyxml的整体处理流程.

    正文:

      还是先回顾下之前看的tinyxml的结构图吧.

      

      从图上我们可以看到,TiXmlAttribute并不是继承与TiXmlNode中,虽然其是xml的元素之一,在实现上很多也是element的叶节点,不过tinyxml并没有这么做.可以先看下TiXmlAttribute的声明.

    View Code

      TiXmlAttribute提供了少部分功能的转化函数.不过特殊的是其Next函数以及Previous函数的实现比较特别.

    View Code

    原因在于,tinyxml使用了循环双向链表进行处理.看下面的TiXmlAttributeSet就可以看得出了.作者给出的理由是:他喜欢循环链表.另外,说明了相对于典型双向链表的独立性(这个我也没搞明白是怎么回事).

    TiXmlAttributeSet是一个工具类,其负责管理Element中的attribute.提供了添加,删除,查找等功能,使得代码更为简洁.

    复制代码
     1 //折叠起来总是有BUG.打不开.所以就只要不折叠了...
     2 class TiXmlAttributeSet
     3 {
     4 public:
     5     //构造和析构函数,构造函数就是把sentinel的头尾连在一起,而析构则是两句assert,判断是否所有元素被移除.
     6 
     7     void Add( TiXmlAttribute* attribute );
     8     void Remove( TiXmlAttribute* attribute );
     9 
    10     //有元素返回,没元素返回null
    11     const TiXmlAttribute* First()    const    { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
    12     TiXmlAttribute* First()                    { return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
    13     const TiXmlAttribute* Last() const        { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    14     TiXmlAttribute* Last()                    { return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
    15 
    16     //查找
    17     TiXmlAttribute*    Find( const char* _name ) const;
    18     TiXmlAttribute* FindOrCreate( const char* _name );
    19     ///stl版本
    20     ///...
    21 
    22 private:
    23     //因为TiXmlAttribute禁止复制,因此AttributeSet也禁止
    24     TiXmlAttributeSet( const TiXmlAttributeSet& );    
    25     void operator=( const TiXmlAttributeSet& );    
    26 
    27     TiXmlAttribute sentinel;//循环链表的头.其目的在于做为头和尾的区分.
    28 };
    复制代码

    可以看看循环链表的处理.

    View Code

    在查看了attribute的处理后,我们就可以看看element的处理了.

    View Code

    剩下的几个元素,如declaration,unknown,text,comment都和element差别不大.我们直接来看TiXmlDocument:

    View Code

     大部分只是简单的设置,我们就着重挑几个感兴趣的看看.

    首先是文件操作,LoadFile以及SaveFile

    View Code

    接下来是我们用于输出的Print函数:

    View Code

    这里用到了多态的方式,来实现相应的函数调用.

    而生成所有xml树的方法Parse也是想同的想法.

     这里就只列举了TiXmlDocument和TiXmlElement的方法.其他的都是类似的处理方式.

    View Code

    后语:

      关于tinyxml的介绍大致到这里了.本文介绍了tinyxml的整体处理流程以及其实现的一些细节.之前也有读者提示说tinyxml很慢.而慢的原因有很多,一个是其用了很多多态,而多态是有一定的代价的.另外,其整体实现都是以树的方式完成的,包括element的属性是以链表的方式实现的,查找等效率都比较低下.

  • 相关阅读:
    React38路由守卫的实现和使用以及Route的不同渲染方式解析
    React37嵌套路由及路由重定向
    React36react-router的路由传参取参
    ElasticSearch总结3-聚合
    ElasticSearch总结2-高级搜索
    [转]Druid连接池泄露引发的血案!
    Swagger的Starter使用及增强
    MySQL问题排查
    ElasticSearch总结1-查询表达式
    使用Spring Validation优雅地进行参数校验
  • 原文地址:https://www.cnblogs.com/shmilxu/p/4831416.html
Copyright © 2011-2022 走看看