TinyXML簡介
TinyXML是目前非常流行的一款基于DOM模型的XML解析器,簡單易用且小巧玲瓏,非常適合存儲簡單數(shù)據(jù),配置文件,對象序列化等數(shù)據(jù)量不是很大的操作,尤其適用于游戲開發(fā),在Nebula2,CEGUI等開源項目中都有使用。本文對TinyXML讀寫XML文件進(jìn)行了重新封裝,能方便的解決XML文檔讀寫。
DOM - Document Object Model
將整篇XML文檔一次性解析并讀入內(nèi)存,保存為一個對象供用戶訪問。
SAX - Simple API for XML
SAX的XML解析方式是基于事件回調(diào)的,解析器在每遇到一個XML元素時都會產(chǎn)生一個事件,并執(zhí)行由用戶提供的處理函數(shù)。
TinyXML類結(jié)構(gòu)
[TiXmlBase] 所有TinyXML類的基類,保存該結(jié)點(diǎn)或?qū)傩栽赬ML原文中的信息。
[TiXmlAttribute] XML結(jié)點(diǎn)屬性,一個鍵值對
[TiXmlNode] XML結(jié)點(diǎn)的基類,封裝了對XML文檔樹形結(jié)構(gòu)進(jìn)行操作和維護(hù)的方法
[TiXmlComment] XML注釋結(jié)點(diǎn)
[TiXmlDeclaration] XML聲明結(jié)點(diǎn)
[TiXmlDocument] XML文檔結(jié)點(diǎn)(一般為一篇XML文檔的根結(jié)點(diǎn))
[TiXmlElement] XML結(jié)點(diǎn)
[TiXmlText] XML文本結(jié)點(diǎn)
[TiXmlUnknown] 含有未知標(biāo)簽的XML結(jié)點(diǎn)
[TiXmlHandle] 封裝了一個結(jié)點(diǎn)的指針,在對該指針進(jìn)行查詢時將自動進(jìn)行空指針交驗
[TiXmlVisitor] 遍歷器接口,描述了每個節(jié)點(diǎn)的處理方法,由子類實(shí)現(xiàn)
[TiXmlPrinter] Printer遍歷器
l 讀取XML文件
TiXmlDocument doc("test.xml");
doc.LoadFile("test.xml");
l 寫入XML文件
TiXmlDocument doc;
……
doc.SaveFile("test.xml");
l 遍歷XML文檔
首先以FirstChild獲得第一個自節(jié)點(diǎn),然后以NextSibling獲取下個兄弟節(jié)點(diǎn);如此遞歸遍歷所有節(jié)點(diǎn)即可。
TiXmlNode::FirstChild();
TiXmlNode::NextSibling();
l 構(gòu)造XML文檔
將指定節(jié)點(diǎn)插入當(dāng)前節(jié)點(diǎn)子節(jié)點(diǎn)隊列的末尾
TiXmlNode::LinkEndChild();
設(shè)置指定節(jié)點(diǎn)的屬性
TiXmlElement::SetAttribute();
TiXmlElement::SetDoubleAttribute();
XML讀寫的邏輯封裝
針對不同的應(yīng)用對XML的讀寫進(jìn)行再次封裝能提升工作的效率和代碼的可讀性等。
#pragma once
#include "stdafx.h" #include "tinyxml.h" //XML 文件的讀寫 class AttXMLDoc ...{ public: AttXMLDoc(void); ~AttXMLDoc(void); //XML讀寫迭代器 void BeginExchange(const char* szFileName,const char* szAttName,bool bSave); bool NextAtt(); //讀寫XML節(jié)點(diǎn) void ExchangeField(const char* szFieldName,DWORD& val); void ExchangeField(const char* szFieldName,WORD& val); void ExchangeField(const char* szFieldName,BYTE& val); void ExchangeField(const char* szFieldName,int& val); void ExchangeField(const char* szFieldName,bool& val); void ExchangeField(const char* szFieldName,float& val); void ExchangeField(const char* szFieldName,char* szValBuf,int bufLen); //XML讀寫迭代器 void EndExchange(); private: TiXmlDocument m_doc; TiXmlElement *m_rootElement; TiXmlElement *m_curElement; bool m_bSave; string m_szName; }; 源文件實(shí)現(xiàn):
#include "StdAfx.h"
#include ".attxmldoc.h" AttXMLDoc::AttXMLDoc(void) ...{ m_curElement = NULL; m_rootElement = NULL; m_bSave = true; } AttXMLDoc::~AttXMLDoc(void) ...{ } char eleName[256]="Att"; void AttXMLDoc::BeginExchange(const char* szFileName,const char* szAttName,bool bSave) ...{ m_bSave = bSave; m_szName = szFileName; if(bSave) ...{ TiXmlDeclaration *decl = new TiXmlDeclaration("1.0","GB2312","yes"); m_doc.LinkEndChild(decl); m_rootElement = new TiXmlElement(szAttName); m_doc.LinkEndChild(m_rootElement); } else ...{ m_doc.LoadFile(szFileName); m_rootElement = m_doc.RootElement(); m_curElement = m_rootElement->FirstChildElement(eleName); } } bool AttXMLDoc::NextAtt() ...{ if(m_bSave) ...{ if(m_curElement != NULL) m_rootElement->LinkEndChild(m_curElement); m_curElement = new TiXmlElement(eleName); return true; } else ...{ m_curElement = m_curElement->NextSiblingElement(eleName); return m_curElement!=NULL; } } void AttXMLDoc::ExchangeField(const char* szFieldName,int& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,val); } else ...{ const char* szFind = m_curElement->Attribute(szFieldName,&val); ASSERT(szFind != NULL); } } void AttXMLDoc::ExchangeField(const char* szFieldName,bool& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,val); } else ...{ int _val = 0; const char* szFind = m_curElement->Attribute(szFieldName,&_val); ASSERT(szFind != NULL); val = _val!=0 ; } } void AttXMLDoc::ExchangeField(const char* szFieldName,WORD& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,val); } else ...{ int _val = 0; const char* szFind = m_curElement->Attribute(szFieldName,&_val); ASSERT(szFind != NULL); val = (WORD)_val ; } } void AttXMLDoc::ExchangeField(const char* szFieldName,BYTE& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,val); } else ...{ int _val = 0; const char* szFind = m_curElement->Attribute(szFieldName,&_val); ASSERT(szFind != NULL); val = (BYTE)_val ; } } void AttXMLDoc::ExchangeField(const char* szFieldName,DWORD& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,val); } else ...{ int _val = 0; const char* szFind = m_curElement->Attribute(szFieldName,&_val); ASSERT(szFind != NULL); val = _val; } } void AttXMLDoc::ExchangeField(const char* szFieldName,float& val) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetDoubleAttribute(szFieldName,val); } else ...{ double _val = 0; const char* szFind = m_curElement->Attribute(szFieldName,&_val); ASSERT(szFind != NULL); val = (float)_val; } } void AttXMLDoc::ExchangeField(const char* szFieldName,char* szValBuf,int bufLen) ...{ ASSERT(m_curElement != NULL ); if(m_bSave) ...{ m_curElement->SetAttribute(szFieldName,szValBuf); } else ...{ const char* szFind = m_curElement->Attribute(szFieldName); if(szFind != NULL) strncpy(szValBuf,szFind,bufLen-1); } } void AttXMLDoc::EndExchange() ...{ if(m_bSave) ...{ if(m_curElement != NULL) ...{ m_rootElement->LinkEndChild(m_curElement); m_doc.SaveFile(m_szName.c_str()); } } } 讀寫XML文件實(shí)例:(略) XML文件的讀寫在開發(fā)中起這很重要的作用,C++本身沒有提供XML解析器,TinyXML是一個小巧高效實(shí)用的XML文檔解析器,好好利用起來會很大程度上提升工作效率。
|
|