用tinyxml创建xml文件

用tinyxml创建xml文件,第1张

——盯迹租需要的包

#include <XMLDoc.hpp>

——相关说明

_di_IXMLDocument 为模板类

typedef System::DelphiInterface<IXMLDocument > _di_IXMLDocument

_di_IXMLNode

typedef System::DelphiInterface<IXMLNode > _di_IXMLNode

_di_IXMLNodeList 同

——类方法

//设置参数

void TXXX::setOptions(String name,String value){

//创建文档对象

_di_IXMLDocument XMLDoc = LoadXMLDocument(L"文件路径"州纳)

XMLDoc->Active=true

//文档根节点凯兆

_di_IXMLNode root = XMLDoc->DocumentElement

//想要查找节点

_di_IXMLNode tempNode

//调用搜索方法

searchXml(name,root,tempNode)

// 处理

if(tempNode!=NULL)

tempNode->SetText(value)

XMLDoc->SaveToFile(L"文件路径")

}

//递归搜索参数节点树

void TXXX::searchXml(String name,_di_IXMLNode &Parent_Node,_di_IXMLNode&tempNode){

_di_IXMLNode Child_Node //子结点

//子节点列表

_di_IXMLNodeList list = Parent_Node->ChildNodes

for(int i=0i<list->Counti++)

{

Child_Node = list->Get(i)

//递归结束条件

if(Child_Node->GetNodeName()==name)

{

tempNode = Child_Node

break

}

else

{

//递归函数

searchXml(name,Child_Node,tempNode)

}

}

}

创建的格式如下:

复制代码 代码如下:

<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来答疑解析中存在的问题。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12276177.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存