#include "stdafx.h" #include <string> #include <map> #include <vector> #include <list> class XMLNode { public: XMLNode() { } const wchar_t* GetName() { return this->m_name.c_str(); } const wchar_t* GetAttribute(const wchar_t* attrName) { return this->m_attributes[attrName].c_str(); } const wchar_t* GetInnerText() { return this->m_innerText.c_str(); } int GetChildCount() { return (int)this->m_children.size(); } XMLNode* GetChild(int index) { return this->m_children[index]; } void SetName(std::wstring& name) { this->m_name = name; } void SetName(const wchar_t* name) { this->m_name = name; } std::wstring& GetNameString() { return this->m_name; } void AddAttribute(std::wstring& name, std::wstring& value) { this->m_attributes.insert(std::make_pair(name, value)); } void AddChild(XMLNode* child) { this->m_children.push_back(child); } void SetInnerText(std::wstring& innerText) { this->m_innerText = innerText; } public: std::wstring m_name; std::wstring m_innerText; std::map< std::wstring, std::wstring > m_attributes; std::vector< XMLNode* > m_children; }; const int XML_NONE = 0; const int XML_PRE_TAG_PRE_S = 1; const int XML_PRE_TAG_PRE_N = 2; const int XML_PRE_TAG_PRE_N_E = 3; const int XML_TAG_ATTR_N = 4; const int XML_TAG_ATTR = 5; const int XML_TAG_ATTR_V_S = 6; const int XML_TAG_ATTR_V_E = 8; const int XML_PRE_TAG_E = 9; const int XML_INNER = 10; const int XML_POST_TAG_S = 11; const int XML_POST_TAG_N = 12; const int XML_POST_TAG_N_E = 13; const int XML_POST_TAG_E = 14; XMLNode* ParseXML(const wchar_t* xmlText, int len) { XMLNode* root = new XMLNode(); root->SetName(L"/"); std::vector< XMLNode* > nodes; nodes.push_back(root); std::wstring xmlTextString; xmlTextString.assign(xmlText, xmlText + len); const wchar_t* pXMLTextString = xmlTextString.c_str(); const wchar_t* pXMLText = xmlText; const wchar_t* pCurXMLText = xmlText; std::wstring name; std::wstring attrName; std::wstring attrValue; std::wstring innerText; int xmlHit = XML_NONE; wchar_t ch = 0; size_t index = 0; size_t size = xmlTextString.size(); while ( index < size ) { ch = *pXMLText; if ( ch == L'<' ) { switch ( xmlHit ) { case XML_INNER: { innerText.assign(pCurXMLText, pXMLText); nodes.back()->SetInnerText(innerText); } case XML_NONE: case XML_PRE_TAG_E: case XML_POST_TAG_E: { xmlHit = XML_PRE_TAG_PRE_S; pCurXMLText = pXMLText + 1; if ( index + 2 < size && pXMLText[1] == L'?' ) { size_t pos = xmlTextString.find(L"?>", index + 2); if ( pos != std::wstring::npos ) { xmlHit = XML_POST_TAG_E; innerText.assign(pXMLTextString + index + 2, pXMLTextString + pos); index = pos + wcslen(L"?>"); pCurXMLText = pXMLTextString + index; pXMLText = pCurXMLText; if ( !nodes.empty() ) { XMLNode* xmlNode = new XMLNode(); xmlNode->SetName(L"?"); xmlNode->SetInnerText(innerText); nodes.back()->AddChild(xmlNode); } } } else if ( index + 4 < size && pXMLText[1] == L'!' && pXMLText[2] == L'-' && pXMLText[3] == L'-' ) { size_t pos = xmlTextString.find(L"-->", index + 4); if ( pos != std::wstring::npos ) { xmlHit = XML_POST_TAG_E; innerText.assign(pXMLTextString + index + 4, pXMLTextString + pos); index = pos + wcslen(L"-->"); pCurXMLText = pXMLTextString + index; pXMLText = pCurXMLText; if ( !nodes.empty() ) { XMLNode* xmlNode = new XMLNode(); xmlNode->SetName(L"!"); xmlNode->SetInnerText(innerText); nodes.back()->AddChild(xmlNode); } } } else if ( index + 2 < size && pXMLText[1] == L'!' ) { size_t pos = xmlTextString.find(L">", index + 2); if ( pos != std::wstring::npos ) { xmlHit = XML_POST_TAG_E; innerText.assign(pXMLTextString + index + 2, pXMLTextString + pos); index = pos + wcslen(L">"); pCurXMLText = pXMLTextString + index; pXMLText = pCurXMLText; if ( !nodes.empty() ) { XMLNode* xmlNode = new XMLNode(); xmlNode->SetName(L"!"); xmlNode->SetInnerText(innerText); nodes.back()->AddChild(xmlNode); } } } } break; case XML_PRE_TAG_PRE_S: { } break; case XML_PRE_TAG_PRE_N: { } break; case XML_PRE_TAG_PRE_N_E: { } break; case XML_TAG_ATTR_N: { } break; case XML_TAG_ATTR: { } break; case XML_TAG_ATTR_V_S: { } break; case XML_TAG_ATTR_V_E: { } break; case XML_POST_TAG_S: { } break; case XML_POST_TAG_N_E: { } break; case XML_POST_TAG_N: { } break; } } else if ( ch == L'=' ) { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { } break; case XML_PRE_TAG_PRE_N: { } break; case XML_PRE_TAG_PRE_N_E: { } break; case XML_TAG_ATTR_N: { xmlHit = XML_TAG_ATTR; attrName.assign(pCurXMLText, pXMLText); pCurXMLText = pXMLText + 1; } break; case XML_TAG_ATTR: { } break; case XML_TAG_ATTR_V_S: { } break; case XML_TAG_ATTR_V_E: {} break; case XML_PRE_TAG_E: {} break; case XML_INNER: { } break; case XML_POST_TAG_S: {} break; case XML_POST_TAG_N: {} break; case XML_POST_TAG_N_E: {} break; case XML_POST_TAG_E: {} break; } } else if ( ch == L'"' ) { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { } break; case XML_PRE_TAG_PRE_N: { } break; case XML_PRE_TAG_PRE_N_E: { } break; case XML_TAG_ATTR_N: { attrName.assign(pCurXMLText, pXMLText); } case XML_TAG_ATTR: { xmlHit = XML_TAG_ATTR_V_S; pCurXMLText = pXMLText + 1; } break; case XML_TAG_ATTR_V_S: { xmlHit = XML_TAG_ATTR_V_E; if ( !nodes.empty() ) { attrValue.assign(pCurXMLText, pXMLText); nodes.back()->AddAttribute(attrName, attrValue); } pCurXMLText = pXMLText + 1; } break; case XML_TAG_ATTR_V_E: {} break; case XML_PRE_TAG_E: {} break; case XML_INNER: { } break; case XML_POST_TAG_S: {} break; case XML_POST_TAG_N: {} break; case XML_POST_TAG_N_E: {} break; case XML_POST_TAG_E: {} break; } } else if ( ch == L'/' ) { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { xmlHit = XML_POST_TAG_S; pCurXMLText = pXMLText + 1; } break; case XML_TAG_ATTR_V_S: { } break; case XML_PRE_TAG_PRE_N: { name.assign(pCurXMLText, pXMLText); XMLNode* node = new XMLNode(); node->SetName(name); nodes.push_back(node); } case XML_PRE_TAG_PRE_N_E: case XML_TAG_ATTR_N: case XML_TAG_ATTR: case XML_TAG_ATTR_V_E: { xmlHit = XML_POST_TAG_N_E; XMLNode* child = nodes.back(); nodes.pop_back(); if ( !nodes.empty() ) { nodes.back()->AddChild(child); } pCurXMLText = pXMLText + 1; } break; case XML_PRE_TAG_E: { } break; case XML_INNER: { } break; case XML_POST_TAG_S: { } break; case XML_POST_TAG_N: {} break; case XML_POST_TAG_N_E: {} break; case XML_POST_TAG_E: {} break; } } else if ( ch == L'>' ) { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { } break; case XML_PRE_TAG_PRE_N: { name.assign(pCurXMLText, pXMLText); XMLNode* node = new XMLNode(); node->SetName(name); nodes.push_back(node); } case XML_PRE_TAG_PRE_N_E: //case XML_TAG_ATTR_V_S: // { // attrValue.assign(pCurXMLText, pXMLText); // nodes.front()->AddAttribute(attrName, attrValue); // } case XML_TAG_ATTR_V_E: { xmlHit = XML_PRE_TAG_E; pCurXMLText = pXMLText + 1; } break; case XML_TAG_ATTR_N: { } break; case XML_TAG_ATTR: { } break; case XML_PRE_TAG_E: { } break; case XML_INNER: { } break; case XML_POST_TAG_S: { } break; case XML_POST_TAG_N: { //xmlHit = XML_POST_TAG_E; XMLNode* child = nodes.back(); nodes.pop_back(); // XMLNode* last = nodes.back(); if ( !nodes.empty() ) { nodes.back()->AddChild(child); } //pCurXMLText = pXMLText + 1; } // break; case XML_POST_TAG_N_E: { xmlHit = XML_POST_TAG_E; pCurXMLText = pXMLText + 1; } break; case XML_POST_TAG_E: { } break; } } else { if ( ch == 0x0020 || ch == 0x0009 || ch == 0x000A || ch == 0x000B || ch == 0x000C || ch == 0x000D || ch == 0x00A0 || ch == 0x2000 || ch == 0x2001 || ch == 0x2002 || ch == 0x2003 || ch == 0x2004 || ch == 0x2005 || ch == 0x2006 || ch == 0x2007 || ch == 0x2008 || ch == 0x2009 || ch == 0x200A || ch == 0x200B || ch == 0x3000 || ch == 0xFEFF ) { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { } break; case XML_PRE_TAG_PRE_N: { xmlHit = XML_PRE_TAG_PRE_N_E; name.assign(pCurXMLText, pXMLText); XMLNode* node = new XMLNode(); node->SetName(name); nodes.push_back(node); pCurXMLText = pXMLText + 1; } break; case XML_PRE_TAG_PRE_N_E: { } break; case XML_TAG_ATTR_N: { } break; case XML_TAG_ATTR: {} break; case XML_TAG_ATTR_V_S: { } break; case XML_TAG_ATTR_V_E: {} break; case XML_PRE_TAG_E: {} break; case XML_INNER: {} break; case XML_POST_TAG_S: {} break; case XML_POST_TAG_N: { xmlHit = XML_POST_TAG_N_E; XMLNode* child = nodes.back(); nodes.pop_back(); //XMLNode* last = nodes.back(); if ( !nodes.empty() ) { nodes.back()->AddChild(child); } pCurXMLText = pXMLText + 1; } break; case XML_POST_TAG_N_E: { } break; case XML_POST_TAG_E: {} break; } } else { switch ( xmlHit ) { case XML_NONE: { } break; case XML_PRE_TAG_PRE_S: { xmlHit = XML_PRE_TAG_PRE_N; pCurXMLText = pXMLText; } break; case XML_PRE_TAG_PRE_N: { } break; case XML_PRE_TAG_PRE_N_E: { xmlHit = XML_TAG_ATTR_N; pCurXMLText = pXMLText; } break; case XML_TAG_ATTR_N: {} break; case XML_TAG_ATTR: { /*xmlHit = XML_TAG_ATTR_V_S; pCurXMLText = pXMLText;*/ } break; case XML_TAG_ATTR_V_S: { } break; case XML_TAG_ATTR_V_E: { xmlHit = XML_TAG_ATTR_N; pCurXMLText = pXMLText; } break; case XML_PRE_TAG_E: { xmlHit = XML_INNER; pCurXMLText = pXMLText; } break; case XML_INNER: {} break; case XML_POST_TAG_S: { xmlHit = XML_POST_TAG_N; pCurXMLText = pXMLText; } break; case XML_POST_TAG_N: { } break; case XML_POST_TAG_N_E: {} break; case XML_POST_TAG_E: {} break; } } } pXMLText++; index++; } return root; } int _tmain(int argc, _TCHAR* argv[]) { std::wstring XMLText; FILE* pFile = ::_wfopen(L"youfilename.xml", L"r+"); wchar_t buffer[1024]; while (!feof(pFile) ) { wchar_t* ret = fgetws(buffer, 1024, pFile); if ( ret != NULL ) { XMLText += ret; } } ::fclose(pFile); XMLNode* root = ParseXML(XMLText.c_str(), XMLText.size()); std::list< XMLNode* > nodes; nodes.push_back(root); while ( !nodes.empty() ) { XMLNode* xmlNode = nodes.front(); nodes.pop_front(); for(int cnt = 0; cnt < xmlNode->GetChildCount(); cnt++) { XMLNode* child = xmlNode->GetChild(cnt); std::wcout << " NAME:" << child->GetName() << L" INNERTEXT:" << child->GetInnerText(); for(std::map< std::wstring, std::wstring >::iterator iter = child->m_attributes.begin(); iter != child->m_attributes.end(); iter++ ) { std::wcout << " ATTRNAME:" << iter->first.c_str() << " ATTRVAL:" << iter->second.c_str(); } std::wcout<<std::endl; nodes.push_back(child); } } return 0; }