#include "XmlDoc.h" #include "../Exception.h" using namespace std; void xml::XmlDoc::XmlSetDoc(string xmlpath) { TiXmlDocument * tmpxmldoc = new TiXmlDocument(xmlpath); // Load test if ( !tmpxmldoc->LoadFile()) throw Exception("XmlDoc::SetDoc","xmldoc->LoadFile() Failed to open: " + xmlpath); XmlSetDoc(tmpxmldoc); } void xml::XmlDoc::XmlSetDoc(TiXmlDocument * xmldoc) { if(_xmldoc) delete _xmldoc; if(_subxmldoc) delete _subxmldoc; _xmldoc = NULL; _subxmldoc = NULL; _tag = NULL; _basetag = NULL; _xmldoc = xmldoc; // ID file type if ((_filetag = _xmldoc->FirstChildElement("scenario"))) _filetype = SCENARIO; else if ((_filetag = _xmldoc->FirstChildElement("player"))) _filetype = PLAYER; else if ((_filetag = _xmldoc->FirstChildElement("xmlelementinit"))) _filetype = XMLINIT; if(!_filetag) throw Exception("XmlDoc::SetDoc","No known XML root tag was found! File: " + xmldoc->ValueStr()); _tag = _filetag->FirstChildElement(); // If xml file is Init type then load data directly, else return and wait if( _filetype == XMLINIT) XmlElementInit(); } xml::XmlDoc::~XmlDoc() { if(_xmldoc) { _xmldoc->Clear(); delete _xmldoc; } if(_subxmldoc) { _xmldoc->Clear(); delete _subxmldoc; } } /****** Private ********/ void xml::XmlDoc::SubFile(string xmlpath) { // Remove any old open file if(_subxmldoc) { _subxmldoc->Clear(); delete _subxmldoc; _subxmldoc = NULL; } _subxmldoc = new TiXmlDocument(data_dir + xmlpath); // Load test if ( !_subxmldoc->LoadFile()) throw Exception("XmlDoc::SubFile","subxmldoc->LoadFile() Failed to open: " + data_dir + xmlpath); // store old location and use new file _basetag = _tag; _tag = _subxmldoc->FirstChildElement(); } void xml::XmlDoc::UnSubFile() { // Check if there is a subfile first if(_subxmldoc) { // return to old tag _tag = _basetag; _subxmldoc->Clear(); delete _subxmldoc; _subxmldoc = NULL; } } void xml::XmlDoc::XmlElementInit() { TiXmlElement *el = 0; // Look at all basetags inside the root tag for(el = _tag; el; el = el->NextSiblingElement()) if(!el->ValueStr().compare("basetag")) { XmlTag * aXmlTag = NULL; pair< XmlTagmap::iterator, bool > sucess = make_pair(_element_tags.begin(), true); sucess = _element_tags.insert(make_pair(el->GetText(), aXmlTag = new XmlTag(TAG_BASE))); if(!sucess.second) throw Exception("XmlDoc::XmlInit()","Duplicate XML Base tag: " + (string)el->GetText()); ReadBaseTag(el, aXmlTag); } } void xml::XmlDoc::ReadBaseTag(TiXmlElement * basetag, XmlTag * parent) { TiXmlElement *el = 0; for(el = basetag->FirstChildElement(); el; el = el->NextSiblingElement()) { if(!el->ValueStr().compare("value")) { // Found a value now add it to the parent XmlTag map with tags int type = TAG_NOTYPE; if(!((string)el->Attribute("type")).compare("int")) type = TAG_INT; else if(!((string)el->Attribute("type")).compare("string")) type = TAG_STRING; if(!parent->InsertSubTag(el->GetText(), type)) throw Exception("XmlDoc::ReadBaseTag","Failed to InsertSubTag: " + (string)el->GetText()); } else if(!el->ValueStr().compare("subtag")) { // Found a subtag create new XmlTag and place values inside new XmlTag, map _tags. XmlTag * aXmlTag = parent->InsertSubTag(el->GetText(), TAG_BASE); if(!aXmlTag) throw Exception("XmlDoc::ReadBaseTag","Failed to InsertSubTag: " + (string)el->GetText()); ReadSubTag(el, aXmlTag); } } } void xml::XmlDoc::ReadSubTag(TiXmlElement * subtag, XmlTag * parent) { TiXmlElement *el = 0; for(el = subtag->FirstChildElement(); el; el = el->NextSiblingElement()) { if(!el->ValueStr().compare("value")) { // Found a value now add it to the parent XmlTag map with tags int type = TAG_NOTYPE; if(!((string)el->Attribute("type")).compare("int")) type = TAG_INT; else if(!((string)el->Attribute("type")).compare("string")) type = TAG_STRING; parent->InsertSubTag(el->GetText(), type); } } }