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

在上篇博客中,大概了解了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来答疑解析中存在的问题。

时间: 2024-09-21 01:36:16

如何利用tinyxml操纵xml及注意问题_C 语言的相关文章

C语言实现xml构造解析器_C 语言

纯C实现xml构造解析器,所有实现只有一个.c一个.h文件组成,简单易用,易于扩展. #include <string.h> #include <stdio.h> #include <stdlib.h> #include "sxml.h" #define LUA_SCRIPT "function fun()\n\ int a;\n\ a = 10;\n\ return a;\n\ end" int main() { sxml_fi

C语言连接并操作Sedna XML数据库的方法_C 语言

本文实例讲述了C语言连接并操作Sedna XML数据库的方法.分享给大家供大家参考.具体如下: #include "libsedna.h" #include "stdio.h" int handle_error(SednaConnection* conn, const char* op, int close_connection) { printf("%s failed: \n%s\n", op, SEgetLastErrorMsg(conn))

使用boost读取XML文件详细介绍_C 语言

boost读取XML文件 boost中提供了对配置文件读取的支持,它就是:property_tree.     basic_ptree 是property_tree的核心基础.其接口像std::list.可以执行很多基本的元素操作,比如使用begin().end()等.     此外还加入了操作属性树的get().get_child().get_value().data()等额外的操作.     basic_ptree有两个重要的内部定义self_type和value_type.self_typ

C++利用链栈实现表达式求值_C 语言

本文实例为大家分享了C++利用链栈实现表达式求值的具体代码,供大家参考,具体内容如下 #include<iostream.h> typedef int Status; typedef char Cstack; #define OK 1 #define ERROR 0 typedef struct StackNode { Cstack data; struct StackNode *next; }StackNode,*LinkStack; Status InitStack(LinkStack &

stringstream操纵string的方法总结_C 语言

1 split字符串 之前在用C#写代码的时候,用过split函数,可以把一个字符串根据某个分隔符分成若干个字符串数组.在用C++操纵字符串的时候,我一直使用很笨的遍历的方法.为此,我问候过很多次C++标准委员会.直到某一天,我做了一个处理绝对路径的题目. 首先,我要把'/'作为分隔符,把输入字符串split一下.下面是我的代码: string inputString("/home/fun/./../code/"); stringstream ss(inputString); stri

C++利用容器查找重复列功能实现_C 语言

复制代码 代码如下: # include <vector> # include <iostream> # include <set> using namespace std; int main(int argc, char * argv[]) { vector<int> v; //找一些数据来测试 for (int i = 0; i < 50; i++) v.push_back(rand() % 25); for (int i = 0; i <

Scala入门到精通——第二十七节 Scala操纵XML

本节主要内容 XML 字面量 XML内容提取 XML对象序列化及反序列化 XML文件读取与保存 XML模式匹配 1. XML 字面量 XML是一种非常重要的半结构化数据表示方式,目前大量的应用依赖于XML,这些应用或利用XML作为数据交换格式,或利用XML进行文件配置等.像JAVA.C++及其它流行的程序开发语言都是依赖于第三方库来实现XML的操作,例如JAVA经常通过JDOM,DOM4J等XML处理工具进行XML的操纵,但Scala提供了对XML的原生支持,通过scala.xml._包下的类或

VC++中利用MSXML解析XML文档

c++|xml 四.程序实现 下面通过一个具体的实例来说明在VC++中如何利用MSXML解析XML文档. (1)源XML文档(xmlfile.xml)如下: <?xml version="1.0" encoding="GB2312"?> <Device id="10041" name="设备1"> <Type>13</Type> <TypeName>保护</Ty

利用VisualBasic操作XML数据

visual|xml|数据 什么是XML 扩展标记语言XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,而这些标记可以用方便的方式建立,虽然XML占用的空间比二进制数据要占用更多的空间,但XML极其简单易于掌握和使用. XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引.排序.查找.相关一致性等,XML仅仅是展示数据.事实上XML与其他数据表现形式最大的不同是:他极其简单.这是一个看上去有点琐细的优点,但正是