現在很多軟體配置,包括遊戲UI的設定檔都選擇了XML。
有很多開源的XML庫, 例如C++的Xerces,但是這個庫很大,簡單的xml解析,用TinyXML庫就夠了。
網址下載:http://sourceforge.net/projects/tinyxml
裡面也就六個檔案, 嫌麻煩你可以直接產生一個lib,直接使用標頭檔。
還是前面說的多叉樹,用TinyXML寫了一個解析器:
#ifndef XMLSCRIPTPARSER_H_<br />#define XMLSCRIPTPARSER_H_</p><p>#include <iostream><br />#include <string></p><p>#include "Tree.hpp"<br />#include "tinyxml.h"</p><p>namespace util {<br />using namespace kptree;</p><p>template<class DataType><br />class XMLScriptParser : public tree<DataType><br />{<br />std::string file_name;//XML Script Name<br />std::string m_name;//該多叉樹的name<br />public:<br />typedef DataType Type;<br />XMLScriptParser(std::string name);<br />virtual ~XMLScriptParser(){};</p><p>bool loadXMLScript();<br />protected:<br />bool recursParse(TiXmlElement* pTreeNode, pre_order_iterator& parent);<br />};</p><p>template<class DataType><br />XMLScriptParser<DataType>::XMLScriptParser(std::string name)<br />: file_name(name)<br />{}</p><p>template<class DataType><br />bool XMLScriptParser<DataType>::loadXMLScript()<br />{<br />TiXmlDocument doc( file_name.c_str() );<br />if (!doc.LoadFile())<br />return false;</p><p>TiXmlHandle hDoc(&doc);<br />TiXmlElement* pElem;<br />TiXmlHandle hRoot(0);</p><p>// block: name<br />pElem=hDoc.FirstChildElement().Element();<br />// should always have a valid root but handle gracefully if it does<br />if (!pElem)<br />return false;<br />m_name=pElem->Value();//m_name = "HTree"</p><p>// save this for later<br />hRoot=TiXmlHandle(pElem);</p><p>// block: Nodes</p><p>TiXmlElement* pTreeNode = hRoot.FirstChild( "Node" ).Element();</p><p>Type node;<br />//讀取當前節點的name:<br />const char *pName=pTreeNode->Attribute("Name");<br />if (pName)<br />node.name = pName;<br />//讀取當前節點的type:<br />const char *pType=pTreeNode->Attribute("Type");// "ROOT"<br />if (pType)<br />node.type = pType;</p><p>pre_order_iterator parent = begin();<br />parent = insert(parent, node );</p><p>// 解析XML檔案<br />return recursParse( pTreeNode, parent );<br />}</p><p>template<class DataType><br />bool XMLScriptParser<DataType>::recursParse(TiXmlElement* pTreeNode, pre_order_iterator& parent)<br />{<br />if ( pTreeNode == NULL )<br />return true;</p><p>// process block放在迴圈外面也是可以的,貌似區別不大</p><p>for ( pTreeNode = pTreeNode->FirstChildElement();<br /> pTreeNode;<br /> pTreeNode = pTreeNode->NextSiblingElement() )<br />{<br />{//Process Block<br />Type node;</p><p>//讀取當前節點的name:<br />const char *pName=pTreeNode->Attribute("Name");<br />if (pName) node.name=pName;<br />//讀取當前節點的type:<br />const char *pType=pTreeNode->Attribute("Type");<br />if (pType) node.type=pType;</p><p>pre_order_iterator child = append_child(parent, node);<br />//構建一個Type對象傳入append_child函數</p><p>recursParse( pTreeNode, child );<br />}<br />}</p><p>return true;<br />}<br />}</p><p>//////////////////////////////////////////////////////////////////////////<br />//4/29/2009-RYF<br />//實現了XML指令碼解析,沒有必要自己寫了^_^</p><p>#endif
測試代碼:
XMLScriptParser<Joint> parser("tree.xml");<br />parser.loadXMLScript();<br />typedef ScriptParser<Joint>::iterator myIter;<br />for (myIter it = parser.begin(); it != parser.end(); ++it)<br />{<br />cout << "Type = " << (*it).type << "/t";<br />cout << "Name = " << (*it).name << "/n";<br />} cout << endl;
新的XML指令檔如下:
<?xml version="1.0" encoding="UTF-8"?><br /><!--- for the use of building a htree --><br /><HTree><br /> <Node Type="ROOT" Name="1"><br /> <Node Type="JOINT" Name="2"><br /> <Node Type="END" Name="3"><br /> </Node></p><p> <Node Type="JOINT" Name="4"><br /> <Node Type="END" Name="5"><br /> </Node><br /> <Node Type="END" Name="6"><br /> </Node><br /> <Node Type="END" Name="7"><br /> </Node><br /> <Node Type="END" Name="8"><br /> </Node><br /> </Node></p><p> <Node Type="END" Name="9"><br /> </Node></p><p> <Node Type="END" Name="10"><br /> </Node><br /> </Node></p><p> <Node Type="JOINT" Name="11"><br /> <Node Type="JOINT" Name="12"><br /> <Node Type="END" Name="13"><br /> </Node><br /> <Node Type="END" Name="14"><br /> </Node><br /> <Node Type="END" Name="15"><br /> </Node><br /> <Node Type="END" Name="16"><br /> </Node><br /> </Node></p><p> <Node Type="END" Name="17"><br /> </Node><br /> <Node Type="END" Name="18"><br /> </Node><br /> <Node Type="END" Name="19"><br /> </Node><br /> </Node><br /> </Node><br /></HTree>