|
TinyXML簡(jiǎn)介
TinyXML是目前非常流行的一款基于DOM模型的XML解析器,簡(jiǎn)單易用且小巧玲瓏,非常適合存儲(chǔ)簡(jiǎn)單數(shù)據(jù),配置文件,對(duì)象序列化等數(shù)據(jù)量不是很大的操作,尤其適用于游戲開(kāi)發(fā),在Nebula2,CEGUI等開(kāi)源項(xiàng)目中都有使用。本文對(duì)TinyXML讀寫XML文件進(jìn)行了重新封裝,能方便的解決XML文檔讀寫。
DOM - Document Object Model
將整篇XML文檔一次性解析并讀入內(nèi)存,保存為一個(gè)對(duì)象供用戶訪問(wèn)。
SAX - Simple API for XML
SAX的XML解析方式是基于事件回調(diào)的,解析器在每遇到一個(gè)XML元素時(shí)都會(huì)產(chǎn)生一個(gè)事件,并執(zhí)行由用戶提供的處理函數(shù)。
TinyXML類結(jié)構(gòu)
[TiXmlBase] 所有TinyXML類的基類,保存該結(jié)點(diǎn)或?qū)傩栽赬ML原文中的信息。
[TiXmlAttribute] XML結(jié)點(diǎn)屬性,一個(gè)鍵值對(duì)
[TiXmlNode] XML結(jié)點(diǎn)的基類,封裝了對(duì)XML文檔樹(shù)形結(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] 封裝了一個(gè)結(jié)點(diǎn)的指針,在對(duì)該指針進(jìn)行查詢時(shí)將自動(dòng)進(jìn)行空指針交驗(yàn)
[TiXmlVisitor] 遍歷器接口,描述了每個(gè)節(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獲得第一個(gè)自節(jié)點(diǎn),然后以NextSibling獲取下個(gè)兄弟節(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)隊(duì)列的末尾
TiXmlNode::LinkEndChild();
設(shè)置指定節(jié)點(diǎn)的屬性
TiXmlElement::SetAttribute();
TiXmlElement::SetDoubleAttribute();
XML讀寫的邏輯封裝
針對(duì)不同的應(yīng)用對(duì)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文件的讀寫在開(kāi)發(fā)中起這很重要的作用,C++本身沒(méi)有提供XML解析器,TinyXML是一個(gè)小巧高效實(shí)用的XML文檔解析器,好好利用起來(lái)會(huì)很大程度上提升工作效率。
|
|
|