基於tinyxml作的簡單的xml解析。ios
bool CreateXmlFile(string& szFileName) {//建立xml文件,szFilePath爲文件保存的路徑,若建立成功返回true,不然false try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(); TiXmlElement *RootElement = new TiXmlElement("Response"); myDocument->LinkEndChild(RootElement); TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList"); RootElement->LinkEndChild(DeviceListElement); DeviceListElement->SetAttribute("Num", "3"); TiXmlElement *ItemElement = new TiXmlElement("Item"); DeviceListElement->LinkEndChild(ItemElement); TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID"); TiXmlElement *NameElement = new TiXmlElement("Name"); ItemElement->LinkEndChild(DeviceIDElement); ItemElement->LinkEndChild(NameElement); TiXmlText *DeviceIDContent = new TiXmlText("44130000002000000002"); TiXmlText *NameContent = new TiXmlText("測試平臺"); DeviceIDElement->LinkEndChild(DeviceIDContent); NameElement->LinkEndChild(NameContent); myDocument->SaveFile(szFileName.c_str());//保存到文件 } catch (string& e) { return false; } return true; }
建立出來的xml以下:git
<Response> <DeviceList Num="3"> <Item> <DeviceID>44130000002000000002</DeviceID> <Name>測試平臺</Name> </Item> </DeviceList> </Response>
(1)從文件讀取xmlwindows
bool ReadXmlFile(string& szFileName) {//讀取Xml文件,並遍歷 try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str()); myDocument->LoadFile(); //得到根元素,即Response。 TiXmlElement *RootElement = myDocument->RootElement(); //輸出根元素名稱,即輸出Response。 cout << RootElement->Value() << endl; //得到第一個DeviceList節點。 TiXmlElement *DeviceListElement = RootElement->FirstChildElement(); TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute(); cout << NumAttribute->Value()<< endl; //得到第一個Person的name節點和age節點和ID屬性。 TiXmlElement *ItemElement = DeviceListElement->FirstChildElement(); for (int i = 0; i < 3; i++) { if (ItemElement) { TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement(); //這裏注意判斷是否存在,不然容易崩潰 if (DeviceIDElement && DeviceIDElement->FirstChild()) { cout << DeviceIDElement->FirstChild()->Value() << endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement(); if (NameElement && NameElement->FirstChild()) { cout << NameElement->FirstChild()->Value() << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement(); if (ParentIDElement && ParentIDElement->FirstChild()) { cout << ParentIDElement->FirstChild()->Value() << endl; } } } ItemElement = ItemElement->NextSiblingElement(); } } } catch (string& e) { return false; } return true; }
(2)從字符串解析xmlide
bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list) {//讀取Xml文件,並遍歷 try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(); myDocument->Parse(xmlString.c_str()); //得到根元素,即Response。 TiXmlElement *RootElement = myDocument->RootElement(); //輸出根元素名稱,即輸出Response。 cout << RootElement->Value() << endl; //得到第一個DeviceList節點。 TiXmlElement *DeviceListElement = RootElement->FirstChildElement(); TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute(); cout << NumAttribute->Value()<< endl; //得到第一個Person的name節點和age節點和ID屬性。 TiXmlElement *ItemElement = DeviceListElement->FirstChildElement(); ST_DEVICE_INFO device_info ; for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement()) { if (ItemElement) { ST_DEVICE_INFO device_info; TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement(); if (DeviceIDElement && DeviceIDElement->FirstChild()) { string str = ""; str = DeviceIDElement->FirstChild()->Value(); //注意是否須要從utf-8轉爲GBK device_info.m_strID = str.c_str();// UtfToGbk(str.c_str()); cout << "ID "<<device_info.m_strID.c_str()<< endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement(); if (NameElement && NameElement->FirstChild()) { str = ""; str = NameElement->FirstChild()->Value(); device_info.m_strName = str.c_str();// UtfToGbk(str.c_str()); cout << "name "<< device_info.m_strName << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement(); if (ParentIDElement && ParentIDElement->FirstChild()) { str = ""; str = ParentIDElement->FirstChild()->Value(); device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str()); cout << "m_strParentID "<<device_info.m_strParentID.c_str()<< endl; } device_info.m_nStatus = 1; device_list.push_back(device_info); } } else { continue; } } } } catch (string& e) { return false; } return true; }
從文件解析xml與從字符串解析xml的不一樣僅僅在加載xml的方式不一樣。測試
從文件是:spa
TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str()); //szFileName爲文件路徑名 myDocument->LoadFile();
從字符串加載是:code
TiXmlDocument *myDocument = new TiXmlDocument(); myDocument->Parse(xmlString.c_str()); //xmlString是字符串
如字符串能夠爲:xml
string xmlStr = "\ <?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \ <Response>\ <DeviceList Num=\"3\">\ <Item>\ <DeviceID>44130000002000000002</DeviceID>\ <Name>測試平臺</Name>\ </Item>\ <Item>\ <DeviceID>441301</DeviceID>\ <Name>惠州市</Name>\ <ParentID>44130000002000000002</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ </DeviceList>\ </Response>" ;
有的時候須要從UTF-8轉GBK,不然會亂碼:對象
std::string UtfToGbk(const char* utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; return str; }
如下是VS2013上的一個例子,搞怪的是utf-8轉成GBK也不會亂碼,轉成GBK反而會亂碼,緣由不明。blog
// xmlTest.cpp : 定義控制檯應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <string> #include <windows.h> #include <atlstr.h> #include <vector> #define TIXML_USE_STL #include "tinyxml.h" #include "tinystr.h" #pragma comment(lib,"tinyxmlSTL.lib") using namespace std; struct ST_DEVICE_INFO { string m_strID; //設備ID string m_strParentID; //父ID string m_strName; //設備名 int m_nType; //類型 int m_nStatus; //狀態 float m_fLongitude; //經度 float m_fLatitude; //緯度 ST_DEVICE_INFO() { m_strID.clear(); m_strParentID.clear(); m_strName.clear(); m_nType = 0; m_nStatus = 0; m_fLongitude = 0; m_fLatitude = 0; } }; typedef vector<ST_DEVICE_INFO> VEC_DEVICE; std::string UtfToGbk(const char* utf8) { int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); wchar_t* wstr = new wchar_t[len + 1]; memset(wstr, 0, len + 1); MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len); len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL); char* str = new char[len + 1]; memset(str, 0, len + 1); WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL); if (wstr) delete[] wstr; return str; } bool CreateXmlFile(string& szFileName) {//建立xml文件,szFilePath爲文件保存的路徑,若建立成功返回true,不然false try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(); TiXmlElement *RootElement = new TiXmlElement("Response"); myDocument->LinkEndChild(RootElement); TiXmlElement *DeviceListElement = new TiXmlElement("DeviceList"); RootElement->LinkEndChild(DeviceListElement); DeviceListElement->SetAttribute("Num", "3"); TiXmlElement *ItemElement = new TiXmlElement("Item"); DeviceListElement->LinkEndChild(ItemElement); TiXmlElement *DeviceIDElement = new TiXmlElement("DeviceID"); TiXmlElement *NameElement = new TiXmlElement("Name"); ItemElement->LinkEndChild(DeviceIDElement); ItemElement->LinkEndChild(NameElement); TiXmlText *DeviceIDContent = new TiXmlText("44130000002000000002"); TiXmlText *NameContent = new TiXmlText("測試平臺"); DeviceIDElement->LinkEndChild(DeviceIDContent); NameElement->LinkEndChild(NameContent); myDocument->SaveFile(szFileName.c_str());//保存到文件 } catch (string& e) { return false; } return true; } bool ReadXmlFile(string& szFileName) {//讀取Xml文件,並遍歷 try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(szFileName.c_str()); myDocument->LoadFile(); //得到根元素,即Response。 TiXmlElement *RootElement = myDocument->RootElement(); //輸出根元素名稱,即輸出Response。 cout << RootElement->Value() << endl; //得到第一個DeviceList節點。 TiXmlElement *DeviceListElement = RootElement->FirstChildElement(); TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute(); cout << NumAttribute->Value()<< endl; //得到第一個Person的name節點和age節點和ID屬性。 TiXmlElement *ItemElement = DeviceListElement->FirstChildElement(); for (int i = 0; i < 3; i++) { if (ItemElement) { TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement(); //這裏注意判斷是否存在,不然容易崩潰 if (DeviceIDElement && DeviceIDElement->FirstChild()) { cout << DeviceIDElement->FirstChild()->Value() << endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement(); if (NameElement && NameElement->FirstChild()) { cout << NameElement->FirstChild()->Value() << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement(); if (ParentIDElement && ParentIDElement->FirstChild()) { cout << ParentIDElement->FirstChild()->Value() << endl; } } } ItemElement = ItemElement->NextSiblingElement(); } } } catch (string& e) { return false; } return true; } bool ReadXmlString(string& xmlString, VEC_DEVICE& device_list) {//讀取Xml文件,並遍歷 try { //建立一個XML的文檔對象。 TiXmlDocument *myDocument = new TiXmlDocument(); myDocument->Parse(xmlString.c_str()); //得到根元素,即Response。 TiXmlElement *RootElement = myDocument->RootElement(); //輸出根元素名稱,即輸出Response。 cout << RootElement->Value() << endl; //得到第一個DeviceList節點。 TiXmlElement *DeviceListElement = RootElement->FirstChildElement(); TiXmlAttribute *NumAttribute = DeviceListElement->FirstAttribute(); cout << NumAttribute->Value()<< endl; //得到第一個Person的name節點和age節點和ID屬性。 TiXmlElement *ItemElement = DeviceListElement->FirstChildElement(); ST_DEVICE_INFO device_info ; for (; ItemElement != NULL; ItemElement = ItemElement->NextSiblingElement()) { if (ItemElement) { ST_DEVICE_INFO device_info; TiXmlElement *DeviceIDElement = ItemElement->FirstChildElement(); if (DeviceIDElement && DeviceIDElement->FirstChild()) { string str = ""; str = DeviceIDElement->FirstChild()->Value(); //注意是否須要從utf-8轉爲GBK device_info.m_strID = str.c_str();// UtfToGbk(str.c_str()); cout << "ID "<<device_info.m_strID.c_str()<< endl; TiXmlElement *NameElement = DeviceIDElement->NextSiblingElement(); if (NameElement && NameElement->FirstChild()) { str = ""; str = NameElement->FirstChild()->Value(); device_info.m_strName = str.c_str();// UtfToGbk(str.c_str()); cout << "name "<< device_info.m_strName << endl; TiXmlElement *ParentIDElement = NameElement->NextSiblingElement(); if (ParentIDElement && ParentIDElement->FirstChild()) { str = ""; str = ParentIDElement->FirstChild()->Value(); device_info.m_strParentID = str.c_str();// UtfToGbk(str.c_str()); cout << "m_strParentID "<<device_info.m_strParentID.c_str()<< endl; } device_info.m_nStatus = 1; device_list.push_back(device_info); } } else { continue; } } } } catch (string& e) { return false; } return true; } int _tmain(int argc, _TCHAR* argv[]) { string fileName = "test.xml"; CreateXmlFile(fileName); cout << "xml文件解析:" << endl; ReadXmlFile(fileName); cout << endl; cout << "字符串解析:" << endl; string xmlStr = "\ <?xml version=\"1.0\" encoding=\"utf - 8\" standalone=\"no\" ?> \ <Response>\ <DeviceList Num=\"3\">\ <Item>\ <DeviceID>44130000002000000002</DeviceID>\ <Name>測試平臺</Name>\ </Item>\ <Item>\ <DeviceID>441301</DeviceID>\ <Name>惠州市</Name>\ <ParentID>44130000002000000002</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ <Item>\ <DeviceID>44130000002000000068</DeviceID>\ <Name>郵政儲蓄門口</Name>\ <ParentID>441301</ParentID>\ </Item>\ </DeviceList>\ </Response>" ; VEC_DEVICE device_list ; device_list.clear() ; ReadXmlString(xmlStr, device_list) ; cout << endl; for (int i = 0; i < device_list.size(); i++) { cout<< "設備ID:" <<device_list[i].m_strID<<" 設備名稱:"<<device_list[i].m_strName<<" 父ID: "<<device_list[i].m_strParentID<<endl ; } system("pause"); return 0; }
運行結果: