當前位置:編程學習大全網 - 腳本源碼 - 如何利用tinyxml操縱xml及註意問題

如何利用tinyxml操縱xml及註意問題

創建的格式如下:

復制代碼 代碼如下:

<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來答疑解析中存在的問題。

  • 上一篇:請問長城車牌的標誌
  • 下一篇:烏江鎮是哪個省的
  • copyright 2024編程學習大全網