如何利用tinyxml操纵xml及注意问题

在上篇博客中,大概了解了tinyxml工具的架构,那这篇博客,我们详细讲述如何利用tinyxml操纵xml。以及在操作的过程中,我们应该注意的问题。
首先把tinyxml源文件导入自己的工程中,效果如下: 
    

实际上,直接添加文件到工程中:如下:



若您的系统是win7或office是2007以上的,添加文件这个功能是不能用的,结果是:或直接崩溃。或没反应。解决方案如下: 
http://www.jb51.net/article/32996.htm
环境准备好了,那么我们开始动手操作吧。正如对数据库表操作一样---增删改查。根据此逻辑,那就从增(创建)开始。
创建的格式如下:


代码如下:

<Persons>
<Person>
<name>lhy</name>
<age>22</age>
</Person>
</Persons>

上篇博客中,我们也介绍了tinyxml解析器中的所有的类以及类之间的关系。
创建上述格式的xml,代码如下:


代码如下:

//创建一个XML的文档对象。
TiXmlDocument *myDocument = new TiXmlDocument();
//创建一个根元素并连接。
TiXmlElement *RootElement = new TiXmlElement("Persons");
myDocument->LinkEndChild(RootElement);
//创建一个Person元素并连接。
TiXmlElement *PersonElement = new TiXmlElement("Person");
RootElement->LinkEndChild(PersonElement);
//创建name元素、age元素并连接。
TiXmlElement *NameElement = new TiXmlElement("name");
TiXmlElement *AgeElement = new TiXmlElement("age");
PersonElement->LinkEndChild(NameElement);
PersonElement->LinkEndChild(AgeElement);
//设置name元素和age元素的内容并连接。
TiXmlText *NameContent = new TiXmlText("lhy");
TiXmlText *AgeContent = new TiXmlText("22");
NameElement->LinkEndChild(NameContent);
AgeElement->LinkEndChild(AgeContent);
myDocument->SaveFile("d:\\lhy\\xml.txt");//保存到文件

只要搞清xml中节点之间的关系,创建不是问题。说白了就是一种辈分关系。
创建搞定了,但是作为C++程序猿,写完之后,总感觉有点别扭,总感觉哪不对劲。你是否也看出其中存在的猫腻?
对了,些许的代码中有大量的New指针。在C++中可没有java中的垃圾回收机制,必须自己来处理这些废弃的垃圾。但是代码中却没有Delete语句?
上网查了资料,发现很多创建代码中,都没有Delete语句?难道是大家都是复制粘贴?还是tinyxml在搞怪?
我总结了以下几点,但是最后在开发的过程中仍是疑问,但是开发的过程中,没有出现问题,所以我的程序就暂时如此了。
说法一:很多文章中,都是new没有delete,是因为tinyxml可以自动释放,自动销毁指针,无需开发者手动释放。
质疑:new出来的可以自动释放?new出来说明是在堆上创建的,什么时候会自动释放?程序结束时,自动释放?那怎么判断程序结束呢?(在一个模块中如何析构另一个模块中的内存区域,我们后面会详谈),所以这种说法不攻自破。
既然tinyxml中有自毁功能,那我们查询其源代码,发现果真如此,tinyxml中在析构函数中,有相应的指针释放。但是并不是每个节点如此的。
源码中的详情:


代码如下:

TiXmlNode::~TiXmlNode()
{
TiXmlNode* node = firstChild;
TiXmlNode* temp = 0;
while ( node )
{
temp = node;
node = node->next;
delete temp;
}
}
void TiXmlNode::Clear()
{
TiXmlNode* node = firstChild;
TiXmlNode* temp = 0;
while ( node )
{
temp = node;
node = node->next;
delete temp;
}
firstChild = 0;
lastChild = 0;
}

我们也知道tinyxml中的类之间存在继承关系。
那我们看tinyxml中的TixmlElement类:


代码如下:

TiXmlElement::~TiXmlElement()
{
ClearThis();
}
void TiXmlElement::ClearThis()
{
Clear();
while( attributeSet.First() )
{
TiXmlAttribute* node = attributeSet.First();
attributeSet.Remove( node );
delete node;
}
}

因为TixmlElement是继承TiXmlNode.但是在TiXmlDocument中并没有发现TiXmlDocument类的析构函数。
第二种说法:TiXmlDocument对象就是这棵树的根结点, 在一个完整的文档中, 除了它, 其余结点必须都是它的后代, 所以TinyXml用了一个很巧妙的方法来析构每一个结点所对应的对象 ---- 每个结点的析构任务都委托给了它的父亲, 这样只要保证父亲被正确析构, 或者调用了父亲的Clear函数, 它的所有后代都会被正确的析构, 所以对整个文档来说只要TiXmlDocument对象被正确析构即可。
在创建的上述代码中,我们发现,所有的节点都是挂在根节点之下的。
其实这句代码: myDocument->LinkEndChild(RootElement);使用了多态方式。类之间的关系如下:
  
并且LinkEndChild源代码如下:它是父类TiXmlNode中的方法


代码如下:

TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
{
assert( node->parent == 0 || node->parent == this );
assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
if ( node->Type() == TiXmlNode::DOCUMENT )
{
delete node;
if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
node->parent = this;
node->prev = lastChild;
node->next = 0;
if ( lastChild )
lastChild->next = node;
else
firstChild = node;// it was an empty list.
lastChild = node;
return node;
}

这样的话:则只要删除根节点,在程序中myDocument,就相当于把删除了TiXmlNode,相当于调用了TiXmlNode的析构函数。
质疑:网上说这种方式,析构是从叶子到树根。根据TiXmlNode中的析构函数,我们可以得出,是从树根到叶子。
但是我们在Delete myDocument时,应该注意一点:
创建文档时,也就是程序段中的myDocument。若是从堆上创建,则需需要手动释放。如我们上述的片段中,就是在堆上创建的。
TiXmlDocument *myDocument=new TiXmlDocument ();
若是从栈上创建,则不须我们手动释放,而是程序自动调用析构函数。同时我们应该注意,其他的元素必须在堆上创建。因为在TiXmlNode析构函数中,是delete的,但是栈上的东东是不须delete,所以除了根节点之外连接的后代节点是必须从堆上创建。
经过我们解释,明白tinyxml中的原理了吗?只要理解了tinyxml中的类的作用以及类之间的关系,看源码是没问题滴哦。
这篇博客根据创建xml小demo解释了其中存在的疑问。那下篇博客中我们会根据解析xml来答疑解析中存在的问题。

(0)

相关推荐

  • 如何利用tinyxml操纵xml及注意问题

    在上篇博客中,大概了解了tinyxml工具的架构,那这篇博客,我们详细讲述如何利用tinyxml操纵xml.以及在操作的过程中,我们应该注意的问题. 首先把tinyxml源文件导入自己的工程中,效果如下:      实际上,直接添加文件到工程中:如下: 若您的系统是win7或office是2007以上的,添加文件这个功能是不能用的,结果是:或直接崩溃.或没反应.解决方案如下: http://www.jb51.net/article/32996.htm 环境准备好了,那么我们开始动手操作吧.正如对

  • c++中用TINYXML解析XML文件

    TinyXML介绍 最近做一个负载均衡的小项目,需要解析xml配置文件,用到了TinyXML,感觉使用起来很容易,给出一个使用TinyXML进行XML解析的简单例子,很多复杂的应用都可以基于本例子的方法来完成. TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树. DOM模型即文档对象模型,是将整个文档分成多个元素(如书.章.节.段等),并利用树型

  • 利用python将xml文件解析成html文件的实现方法

    功能就是题目所述,我的python2.7,装在windows环境,我使用的开发工具是wingide 6.0 1.首先是我设计的简单的一个xml文件,也就是用来解析的源文件 下面是这个文件website.xml内容: <website> <page name="index" title="fuckyou"> <h1>welcome to</h1> <p>this is a moment</p> &

  • Android利用Dom对XML进行增删改查操作详解

    1. 概述 平常我们一般是使用JSON与服务器做数据通信,JSON的话,直接用GSON或者其他库去解析很简单.但是,其他有些服务器会返回XML格式的文件,这时候就需要去读取XML文件了. XML的解析有三种方式,在Android中提供了三种解析XML的方式:DOM(Document Objrect Model) , SAX(Simple API XML) ,以及Android推荐的Pull解析方式,他们也各有弊端,而这里来看看使用DOM的方式. 2. Dom解析 DOM解析器在解析XML文档时,

  • Android利用SAX对XML进行增删改查操作详解

    前言 解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析. DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了. 优点:整个文档读入内存,方便操作:支持修改.删除和重现排列等多种功能. 缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间. 使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU). 为了解决DOM解析存在的问题,就出现了SAX解析.其特点为: 优

  • Android利用Document实现xml读取和写入操作

    本文实例为大家分享了利用Document实现xml读取和写入操作,供大家参考,具体内容如下 首先先来介绍一下什么xml?xml是可扩展标记语言,他可以用来标记数据,定义数据类型.是一种允许用户对自己标记语言进行定义的源语言.解析XML文件的方法有很多方法:dom解析,就是document以及PULL和SAX方法.今天给大家分享一下如何用Document来操作XML. 效果图: 首先先对布局文件进行操作:activity_main.xml: <?xml version="1.0"

  • Python利用命名空间解析XML文档

    问题 你想解析某个XML文档,文档中使用了XML命名空间. 解决方案 考虑下面这个使用了命名空间的文档: <?xml version="1.0" encoding="utf-8"?> <top> <author>David Beazley</author> <content> <html xmlns="http://www.w3.org/1999/xhtml"> <he

  • C++使用TinyXML解析XML

    目录 1.介绍 2.TinyXML配置 3.TinyXML读取和保存文件 3.1 读取xml文件 3.2 读取xml参数 3.3 保存xml参数到文本 3.4 保存xml参数到临时变量 4.TinyXML增删改查 4.1 增 4.2 删 4.3 改 4.4 查 1.介绍 Tinyxml的官方网址:http://www.grinninglizard.com 官方介绍文档:http://www.grinninglizard.com/tinyxmldocs/tutorial0.html 在TinyXM

  • C++中TinyXML读取xml文件用法详解

    目录 前言 XML文件理解 常用的XML类方法使用 总结 前言 TinyXML下载地址:https://sourceforge.net/projects/tinyxml/ 官方文档:TinyXML TinyXML是个解析库,它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h.tinystr.h.tinystr.cpp.tinyxml.cpp.tinyxmlerror.cpp.tinyxmlparser.cpp)导入工程就可以用它的东西了.如果需要

  • 使用asx3m与xstream配合解决flex与java利用httpservice传递xml数据问题

    后端也存在java user object类,利用xstream组件把list中的user对象序列化成xml数据.在flex端通过httpservice使用E4X format格式获取.刚开始自己准备通过e4x技术来解析xml,构造flex user object,类似这样的处理方式: 复制代码 代码如下: public function fromXML(currentNode:XML):void{ userID = new Number(currentNode.userID); userNam

随机推荐