码迷,mamicode.com
首页 > 编程语言 > 详细

C++的XML解析器:TinyXML

时间:2014-08-18 16:27:42      阅读:351      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   文件   

         TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在WindowsLinux中编译。这个解析库的模型通过解析XML文件,然后在内存中生DOM模型,从而让我们很方便的遍历这棵XML树。

下面是该库的类的继承关系:

bubuko.com,布布扣

在TinyXML中,根据XML的各种元素来定义了一些类:

TiXmlBase:整个TinyXML模型的基类。

TiXmlAttribute:对应于XML中的元素的属性。

TiXmlNode:对应于DOM结构中的节点。

TiXmlComment:对应于XML中的注释

TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。

TiXmlDocument:对应于XML的整个文档。

TiXmlElement:对应于XML的元素。

TiXmlText:对应于XML的文字部分

TiXmlUnknown:对应于XML的未知部分。 

TiXmlHandler:定义了针对XML的一些操作。

   Tinyxml使用了两种编译选择:使用标准C的char *类型或者使用STL中的std::string,其中使用预处理器TIXML_USE_STL进行控制,即添加了TIXML_USE_STL为使用std::string的。鉴于STL的广泛使用以及其强大功能,下面我以使用std::string的tinyxml说明。

下面是具体代码实例:

<span style="font-size:18px;">#include<string>
#include <iostream>
#include <exception>
#include "tinyxml.h"
#include "tinystr.h"
using namespace std;
#include <windows.h>
#include <atlstr.h>
CString GetAppPath(){
	TCHAR modulePath[MAX_PATH];
	GetModuleFileName(NULL,modulePath,MAX_PATH);
	CString strModulePath(modulePath);
	strModulePath=strModulePath.Left(strModulePath.ReverseFind('\\'));
	return strModulePath;
}
bool createXMlFile(const string& fullPath){
	try
	{
		//创建一个XML的文档对象。
		TiXmlDocument *myDocument = new TiXmlDocument();
		if (!myDocument)
		{
			return false;
		}
		//定义一个xml文件头部声明 
		TiXmlDeclaration *pDeclartion=new TiXmlDeclaration("1.0","UTF-8","yes");
		if(!pDeclartion){
            return false;
		}
		myDocument->LinkEndChild(pDeclartion);
		//创建一个根元素并连接。
		TiXmlElement *rootElement = new TiXmlElement("Persons");
		if (!rootElement)
		{
			return false;
		}
		myDocument->LinkEndChild(rootElement);

		//创建一个Person元素并连接
		TiXmlElement *personElement=new TiXmlElement("person");
		if (!personElement)
		{
			return false;
		}
		rootElement->LinkEndChild(personElement);
		//设置person元素的属性
		personElement->SetAttribute("ID","1");
		//创建name元素,age元素并连接
		TiXmlElement *nameElement=new TiXmlElement("name");
		if (!nameElement)
		{
			return false;
		}
		TiXmlElement *ageElement=new TiXmlElement("age");
		if (!ageElement)
		{
			return false;
		}
		personElement->LinkEndChild(nameElement);
		personElement->LinkEndChild(ageElement);

		//设置name元素和age元素内容
		TiXmlText *nameContent=new TiXmlText("我是NO1");
		if (!nameContent)
		{
			return false;
		}
		TiXmlText *ageContent=new TiXmlText("22");
		if (!ageContent)
		{
			return false;
		}
		nameElement->LinkEndChild(nameContent);
		ageElement->LinkEndChild(ageContent);

		myDocument->SaveFile(fullPath.c_str());
		delete myDocument;
	}
	catch (exception& e)
	{
		cout<<e.what()<<endl;
		return false;
	}
	return true;
}

bool readXml(const string& fullPath){
	try{
		//创建一个xml文档对象
		TiXmlDocument *myDocument=new TiXmlDocument(fullPath.c_str());
		if (!myDocument)
		{
			return false;
		}
		myDocument->LoadFile();
		//获取根元素,即Persons
		TiXmlElement *rootElement=myDocument->RootElement();
		//输出根元素名称
		cout<<rootElement->Value()<<endl;
		//获取第一个Person节点
		TiXmlElement *firstElement=rootElement->FirstChildElement();

		//获取第一个Person的name节点和age节点
		TiXmlElement *nameElement=firstElement->FirstChildElement();
		TiXmlElement *ageElement=nameElement->NextSiblingElement();

		TiXmlAttribute *idAttribute=firstElement->FirstAttribute();

		cout<<nameElement->FirstChild()->Value()<<endl;
		cout<<ageElement->FirstChild()->Value()<<endl;
		cout<<idAttribute->Value()<<endl;
		delete myDocument;
	}
	catch (exception& e)
	{
		cout<<e.what()<<endl;
		return false;
	}
	return true;

}
/*!
*  /brief 打印xml文件。
*
*  /param XmlFile xml文件全路径。
*  /return 是否成功。true为成功,false表示失败。
*/
bool paintXml(std::string XmlFile)
{
	// 定义一个TiXmlDocument类指针
	TiXmlDocument *pDoc = new TiXmlDocument();
	if (NULL==pDoc)
	{
		return false;
	}
	pDoc->LoadFile(XmlFile.c_str());
	pDoc->Print();
	delete pDoc;
	return true;
}
int main(){
	CString appPath=GetAppPath();
	string fileName="xmlDemo.xml";
	string seperator="\\";
	string fullPath=appPath.GetBuffer(0)+seperator+fileName;
	
	//创建
	createXMlFile(fullPath);
	//打印xml
	paintXml(fullPath);

	cout<<"读取信息如下:"<<endl;
	//读取xml
	readXml(fullPath);
	system("pause");
	return 0;
}</span>
bubuko.com,布布扣











具体代码可下载:

http://download.csdn.net/detail/woshizfs/7699843

关于TinyXMLDocument的撤销问题
       自己写了一个xml读取写入的程序,new和delete本来成对使用,可是在调试过程中程序总是崩溃,出现内存泄漏问题,后来发现有个指针调用为空(C++中的陷阱就在于此)。

另一方面,却发现使用TinyXML过程中使用了好多new来创建节点。C++需要,自己管理内存。new创建的对象都保存在堆上,必须手动delete掉。可我也没做处理,开始迷惑了。

     找了半天,从继承关系来看, 对于一个TinyXMLDocument对象,在析构时,会将其子节点都释放掉,它的子节点都是new出来的,也必须delete掉。但TinyXML的析构函数是空的,什么也没写,不要忘了,TinyXMLDocument是从TinyXMLNode继承而来,在TinyXMLNode的析构函数中,却清楚的写着

TiXmlNode::~TiXmlNode()
{
    TiXmlNode* node = firstChild;
    TiXmlNode* temp = 0;

    while ( node )
    {
        temp = node;
        node = node->next;
        delete temp;
    } 
}

所以,doc对象释放时,会对所有已经连接进来的节点进行释放,所以不需要手动的去释放所new出来的东西。
但是,还需要注意,如果TiXmlDocument对象也是new出来的,则需要对TiXmlDocument对象执行delete,才可以触发析构函数被调用。


C++的XML解析器:TinyXML,布布扣,bubuko.com

C++的XML解析器:TinyXML

标签:style   blog   http   color   使用   os   io   文件   

原文地址:http://blog.csdn.net/zfs_kuai/article/details/38314369

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!