C++中用TinyXML对XML文件进行解析

来源:互联网 发布:照片模糊修复软件 编辑:程序博客网 时间:2024/06/07 18:38

最近老师要求的一个项目中需要在C++对XML文件进行解析,原来只在JAVA中做过类似的解析,然后上了某度了一下,最后搜了一篇关于TinyXML的博客,地址如下:http://blog.csdn.net/mhapdream/article/details/9088363

感觉TinyXML比较好用,准备用它来解析.



TinyXML下载地址:http://sourceforge.net/projects/tinyxml/


下载下来后,只需要将tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp这五文件导入工程即可.


下面举两个例,这两个例子基本囊括XML的一些操作:


#include <iostream>#include "tinyxml.h"#include "tinystr.h"#include <string>#include <windows.h>#include <atlstr.h>using namespace std;CString GetAppPath(){//获取应用程序根目录TCHAR modulePath[MAX_PATH];GetModuleFileName(NULL, modulePath, MAX_PATH);CString strModulePath(modulePath);strModulePath = strModulePath.Left(strModulePath.ReverseFind(_T('\\')));return strModulePath;}bool CreateXmlFile(string& szFileName){//创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则falsetry{//创建一个XML的文档对象。TiXmlDocument *myDocument = new TiXmlDocument();//创建一个根元素并连接。TiXmlElement *RootElement = new TiXmlElement("Persons");myDocument->LinkEndChild(RootElement);//创建一个Person元素并连接。TiXmlElement *PersonElement = new TiXmlElement("Person");RootElement->LinkEndChild(PersonElement);//设置Person元素的属性。PersonElement->SetAttribute("ID", "1");//创建name元素、age元素并连接。TiXmlElement *NameElement = new TiXmlElement("name");TiXmlElement *AgeElement = new TiXmlElement("age");PersonElement->LinkEndChild(NameElement);PersonElement->LinkEndChild(AgeElement);//设置name元素和age元素的内容并连接。TiXmlText *NameContent = new TiXmlText("周星星");TiXmlText *AgeContent = new TiXmlText("22");NameElement->LinkEndChild(NameContent);AgeElement->LinkEndChild(AgeContent);CString appPath = GetAppPath();string seperator = "\\";string fullPath = appPath.GetBuffer(0) +seperator+szFileName;myDocument->SaveFile(fullPath.c_str());//保存到文件}catch (string& e){return false;}return true;}bool ReadXmlFile(string& szFileName){//读取Xml文件,并遍历try{CString appPath = GetAppPath();string seperator = "\\";string fullPath = appPath.GetBuffer(0) +seperator+szFileName;//创建一个XML的文档对象。TiXmlDocument *myDocument = new TiXmlDocument(fullPath.c_str());myDocument->LoadFile();//获得根元素,即Persons。TiXmlElement *RootElement = myDocument->RootElement();//输出根元素名称,即输出Persons。cout << RootElement->Value() << endl;//获得第一个Person节点。TiXmlElement *FirstPerson = RootElement->FirstChildElement();//获得第一个Person的name节点和age节点和ID属性。TiXmlElement *NameElement = FirstPerson->FirstChildElement();TiXmlElement *AgeElement = NameElement->NextSiblingElement();TiXmlAttribute *IDAttribute = FirstPerson->FirstAttribute();//输出第一个Person的name内容,即周星星;age内容,即;ID属性,即。cout << NameElement->FirstChild()->Value() << endl;cout << AgeElement->FirstChild()->Value() << endl;cout << IDAttribute->Value()<< endl;}catch (string& e){return false;}return true;}int main(){string fileName = "info.xml";CreateXmlFile(fileName);ReadXmlFile(fileName);}

生成的XML文件如下:


运行结果如下:




第二个例子比较全面:


#include <string>#include <list>#include <map>#include "tinyxml.h"using namespace std;typedef std::map<std::string,std::string> MessageMap;// a basic window abstraction - demo purposes onlyclass WindowSettings{public:int x,y,w,h;string name;WindowSettings(): x(0), y(0), w(100), h(100), name("Untitled"){}WindowSettings(int x, int y, int w, int h, const string& name){this->x=x;this->y=y;this->w=w;this->h=h;this->name=name;}};class ConnectionSettings{public:string ip;double timeout;};class AppSettings{public:string m_name;MessageMap m_messages;list<WindowSettings> m_windows;ConnectionSettings m_connection;AppSettings() {}void save(const char* pFilename);void load(const char* pFilename);// just to show how to do itvoid setDemoValues(){m_name="MyApp";m_messages.clear();m_messages["Welcome"]="Welcome to "+m_name;m_messages["Farewell"]="Thank you for using "+m_name;m_windows.clear();m_windows.push_back(WindowSettings(15,15,400,250,"Main"));m_connection.ip="Unknown";m_connection.timeout=123.456;}};void AppSettings::save(const char* pFilename){TiXmlDocument doc;  TiXmlElement* msg;TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );  doc.LinkEndChild( decl );  TiXmlElement * root = new TiXmlElement( this->m_name.c_str() );  doc.LinkEndChild( root );  TiXmlComment * comment = new TiXmlComment();comment->SetValue(" Settings for MyApp " );  root->LinkEndChild( comment );  TiXmlElement * msgs = new TiXmlElement( "Messages" );  root->LinkEndChild( msgs );  msg = new TiXmlElement( "Welcome" );  msg->LinkEndChild( new TiXmlText( this->m_messages["Welcome"].c_str() ));  msgs->LinkEndChild( msg );  msg = new TiXmlElement( "Farewell" );  msg->LinkEndChild( new TiXmlText( this->m_messages["Farewell"].c_str() ));  msgs->LinkEndChild( msg );  TiXmlElement * windows = new TiXmlElement( "Windows" );  root->LinkEndChild( windows );  for(list<WindowSettings>::iterator iter = m_windows.begin(); iter != m_windows.end(); iter++){TiXmlElement * window;window = new TiXmlElement( "Window" );  windows->LinkEndChild( window );  window->SetAttribute("name", iter->name.c_str());window->SetAttribute("x", iter->x);window->SetAttribute("y", iter->y);window->SetAttribute("w", iter->w);window->SetAttribute("h", iter->h);}TiXmlElement * cxn = new TiXmlElement( "Connection" );  root->LinkEndChild( cxn );  cxn->SetAttribute("ip", m_connection.ip.c_str());cxn->SetDoubleAttribute("timeout", m_connection.timeout); // floating point attribdoc.SaveFile(pFilename);  }void AppSettings::load(const char* pFilename){TiXmlDocument doc(pFilename);if (!doc.LoadFile()) return;TiXmlHandle hDoc(&doc);TiXmlElement* pElem;TiXmlHandle hRoot(0);// block: name{pElem=hDoc.FirstChildElement().Element();// should always have a valid root but handle gracefully if it doesif (!pElem) return;m_name=pElem->Value();// save this for laterhRoot=TiXmlHandle(pElem);}// block: string table{m_messages.clear(); // trash existing tablepElem=hRoot.FirstChild( "Messages" ).FirstChild().Element();for( pElem; pElem; pElem=pElem->NextSiblingElement()){const char *pKey=pElem->Value();const char *pText=pElem->GetText();if (pKey && pText) {m_messages[pKey]=pText;}}}// block: windows{m_windows.clear(); // trash existing listTiXmlElement* pWindowNode=hRoot.FirstChild( "Windows" ).FirstChild().Element();for( pWindowNode; pWindowNode; pWindowNode=pWindowNode->NextSiblingElement()){WindowSettings w;const char *pName=pWindowNode->Attribute("name");if (pName) w.name=pName;pWindowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-ispWindowNode->QueryIntAttribute("y", &w.y);pWindowNode->QueryIntAttribute("w", &w.w);pWindowNode->QueryIntAttribute("hh", &w.h);m_windows.push_back(w);}}// block: connection{pElem=hRoot.FirstChild("Connection").Element();if (pElem){m_connection.ip=pElem->Attribute("ip");pElem->QueryDoubleAttribute("timeout",&m_connection.timeout);}}}int main(void){// block: customise and save settings{AppSettings settings;settings.m_name="HitchHikerApp";settings.m_messages["Welcome"]="Don't Panic";settings.m_messages["Farewell"]="Thanks for all the fish";settings.m_windows.push_back(WindowSettings(15,25,300,250,"BookFrame"));settings.m_windows.push_back(WindowSettings(5,5,350,50,"BookFrame2"));settings.m_connection.ip="192.168.0.77";settings.m_connection.timeout=42.0;settings.save("appsettings2.xml");}// block: load settings{AppSettings settings;settings.load("appsettings2.xml");printf("%s: %s\n", settings.m_name.c_str(), settings.m_messages["Welcome"].c_str());for(list<WindowSettings>::iterator iter = settings.m_windows.begin(); iter != settings.m_windows.end(); iter++){printf("%s: Show window '%s' at %d,%d (%d x %d)\n", settings.m_name.c_str(), iter->name.c_str(), iter->x, iter->y, iter->w, iter->h);}printf("%s: %s\n", settings.m_name.c_str(), settings.m_messages["Farewell"].c_str());}return 0;}


生成的XML文件如下:




运行结果如下:





0 0