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

在操作tinyxml的过程中,我们应该注意的问题。
首先把tinyxml源文件导入自己的工程中,效果如下: 
    

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


若您的系统是win7或office是2007以上的,添加文件这个功能是不能用的,结果是:或直接崩溃。或没反应。解决方案如下: 
https://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。若是从堆上创建,则需需要手动释放(delete myDocument,同时建议先myDocument.Clear();//清除子节点,后delete myDocument;//清除自己。这里其它子节点虽然是new的,但是不需要单独delete,根节点的Clear或者delete会清除它们的。如我们上述的片段中,就是在堆上创建的。 TiXmlDocument *myDocument=new TiXmlDocument ();
若是从栈上创建,则不须我们手动释放,而是程序自动调用析构函数。同时我们应该注意,其他的元素必须在堆上创建。因为在TiXmlNode析构函数中,是delete的,但是栈上的东东是不须delete,所以除了根节点之外连接的后代节点是必须从堆上创建
经过我们解释,明白tinyxml中的原理了吗?只要理解了tinyxml中的类的作用以及类之间的关系,看源码是没问题滴哦。
这篇博客根据创建xml小demo解释了其中存在的疑问。那下篇博客中我们会根据解析xml来答疑解析中存在的问题。 

转自:https://www.jb51.net/article/32995.htm

原文地址:https://www.cnblogs.com/liushui-sky/p/13918083.html