int readFile(string file) { XMLDocument doc; doc.LoadFile(file.data()); cout << file << "\n"; if(!doc.ErrorID()) { int raio_circulo; XMLElement* janela = doc.FirstChildElement("aplicacao")->FirstChildElement("janela"); const char *titulo = janela->FirstChildElement("titulo")->GetText(); janela->FirstChildElement( "largura" )->QueryIntText( &width ); janela->FirstChildElement( "altura" )->QueryIntText( &height ); janela->FirstChildElement("fundo")->QueryIntAttribute("corR",&corR_fundo); janela->FirstChildElement("fundo")->QueryIntAttribute("corG",&corG_fundo); janela->FirstChildElement("fundo")->QueryIntAttribute("corB",&corB_fundo); XMLElement* circulo = doc.FirstChildElement("aplicacao")->FirstChildElement("circulo"); circulo->QueryIntAttribute( "raio", &raio_circulo); circulo->QueryIntAttribute("corR",&corR_circulo); circulo->QueryIntAttribute("corG",&corG_circulo); circulo->QueryIntAttribute("corB",&corB_circulo); title = std::string(titulo); radius = raio_circulo/(double)width; }else { cout << "Erro ao abrir o arquivo XML "<< file << "\n"; } return doc.ErrorID(); }
void XmlReader::xmlReadContactInfo(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *contacts = root->FirstChildElement("contacts"); for (XMLElement *contact = contacts->FirstChildElement("contact"); contact; contact = contact->NextSiblingElement("contact")) { XMLElement *user2_id = contact->FirstChildElement("user_id"); XMLElement *user2_account = contact->FirstChildElement("user_acount"); XMLElement *user2_name = contact->FirstChildElement("user_name"); printf("user_id: %s\n", user2_id->GetText()); printf("user_account: %s\n", user2_account->GetText()); printf("user_name: %s\n", user2_name->GetText()); printf("\n"); } }
string XMLHandler::LoadLink(string name) { XMLDocument doc; doc.LoadFile("links.xml"); if( doc.Error() ) { cout << "\nERROR:" << doc.ErrorID() << endl; return "ERROR"; } XMLElement* rootNode = doc.FirstChildElement("Links"); if (!rootNode) std::cout << "No Links element" << std::endl; XMLElement* linkNode = rootNode->FirstChildElement("Link"); if(!linkNode) std::cout << "No link elements" << std::endl; // Loop through XML for( ; linkNode != NULL; linkNode = linkNode->NextSiblingElement() ) { if( name == linkNode->Attribute("name") ) { return linkNode->Attribute("url"); } } return "NOTFOUND"; }
int example_1() { XMLDocument doc; doc.LoadFile( "resources/dream.xml" ); return doc.ErrorID(); }
void XmlReader::xmlReadSelfInfo(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *user = root->FirstChildElement("user"); XMLElement *user_id = user->FirstChildElement("user_id"); XMLElement *user1_account = user->FirstChildElement("user_acount"); XMLElement *user_name = user->FirstChildElement("user_name"); XMLElement *big_visit_num = user->FirstChildElement("big_visit_num"); XMLElement *vsp_id = user->FirstChildElement("vsp_id"); XMLElement *vsp_name = user->FirstChildElement("vsp_name"); printf("user_id: %s\n", user_id->GetText()); printf("user1_account: %s\n", user1_account->GetText()); printf("user_name: %s\n", user_name->GetText()); printf("big_visit_num: %s\n", big_visit_num->GetText()); printf("vsp_id: %s\n", vsp_id->GetText()); printf("vsp_name: %s\n", vsp_name->GetText()); printf("================================================\n"); }
int example_2() { static const char* xml = "<element/>"; XMLDocument doc; doc.Parse( xml ); return doc.ErrorID(); }
int main(int argc, char **argv) { string line = ""; if (argc == 1) { cout << "Enter file location: " << std::endl; while (line == "") getline(cin, line); } XMLDocument document; document.LoadFile(argc > 1 ? argv[1] : line.c_str()); if (document.ErrorID() > 0) return document.ErrorID(); else { document.Parse(line.c_str()); auto element = document.FirstChild(); int a =0; } }
//read high scores XML =============================== std::string loadScores ( int player ) { int counter=0; XMLDocument* doc = new XMLDocument(); doc->LoadFile ( "highscore.xml" ); int errorID = doc->ErrorID(); std::string err = doc->ErrorName(); std::string playerString[20][3]; XMLPrinter printer; //std::cout << "Test file loaded. ErrorID = "<<errorID<<" "<<err<<std::endl; if ( errorID!=0 ) return ""; XMLNode* root = doc->FirstChildElement ( "players" ); if ( root == NULL ) { std::cout<<"error xml root"<<std::endl; return ""; } XMLElement* node = root->FirstChildElement ( "player" )->ToElement(); if ( node == NULL ) { std::cout<<"error xml"<<std::endl; return ""; } while ( node->NextSiblingElement() !=NULL && counter<=player ) { XMLElement* element = node->FirstChildElement ( "name" )->ToElement(); if ( element == NULL ) { std::cout<<"error xml"<<std::endl; return ""; } playerString[counter][0] = element->GetText(); //std::cout <<"playerstring="<<playerString[counter][0]<<std::endl; element = element->NextSiblingElement ( "score" )->ToElement(); if ( element == NULL ) { std::cout<<"error xml"<<std::endl; return ""; } playerString[counter][1] = element->GetText(); element = element->NextSiblingElement ( "mode" )->ToElement(); if ( element == NULL ) { std::cout<<"error xml"<<std::endl; return ""; } playerString[counter][2] = element->GetText(); node = node->NextSiblingElement ( "player" )->ToElement(); if ( node == NULL ) { std::cout<<"error xml"<<std::endl; return ""; } counter++; } return playerString[player][0]+", "+playerString[player][1]+", " +playerString[player][2]; }
// Loads the campaign data int _Campaign::Init() { Campaigns.clear(); Log.Write("_Campaign::Init - Loading file irrlamb.xml"); // Open the XML file std::string LevelFile = std::string("levels/main.xml"); XMLDocument Document; if(Document.LoadFile(LevelFile.c_str()) != XML_NO_ERROR) { Log.Write("Error loading level file with error id = %d", Document.ErrorID()); Log.Write("Error string 1: %s", Document.GetErrorStr1()); Log.Write("Error string 2: %s", Document.GetErrorStr2()); Close(); return 0; } // Check for level tag XMLElement *CampaignsElement = Document.FirstChildElement("campaigns"); if(!CampaignsElement) { Log.Write("Could not find campaigns tag"); return 0; } // Load campaigns XMLElement *CampaignElement = CampaignsElement->FirstChildElement("campaign"); for(; CampaignElement != 0; CampaignElement = CampaignElement->NextSiblingElement("campaign")) { CampaignStruct Campaign; Campaign.Name = CampaignElement->Attribute("name"); // Get levels XMLElement *LevelElement = CampaignElement->FirstChildElement("level"); for(; LevelElement != 0; LevelElement = LevelElement->NextSiblingElement("level")) { LevelStruct Level; Level.File = LevelElement->GetText(); Level.DataPath = Game.GetWorkingPath() + "levels/" + Level.File + "/"; Level.Unlocked = 0; LevelElement->QueryIntAttribute("unlocked", &Level.Unlocked); ::Level.Init(Level.File, true); Level.NiceName = ::Level.GetLevelNiceName(); Campaign.Levels.push_back(Level); } Campaigns.push_back(Campaign); } return 1; }
wchar_t *GetProductID(wchar_t *path) { char *buf = NULL; UnZipFile(path, "WMAppManifest.xml", &buf, NULL); char *newBuf = NULL; if (buf) { const char *result = NULL; XMLDocument doc; if (doc.Parse(buf)) { int outputSize = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)buf, -1, NULL, 0, NULL, NULL); newBuf = new char[outputSize]; WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)buf, -1, newBuf, outputSize, NULL, NULL); doc.Parse(newBuf); delete[] newBuf; if (doc.ErrorID()) { return NULL; } } char *levels[] = {"Deployment", "App", "ProductID"}; int levelCount = 3; XMLElement* elem = doc.FirstChildElement(levels[0]); for (int i = 1; i < levelCount; i++) { if (i == (levelCount - 1)) { result = elem->Attribute(levels[i]); } else { elem = elem->FirstChildElement(levels[i]); if (!elem) break; } } if (result) { wchar_t *str = new wchar_t[strlen(result) + 1]; mbstowcs(str, result, strlen(result) + 1); return str; } } return NULL; }
void XmlReader::xmlReadMeetingInfo(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *meetings = root->FirstChildElement("meetings"); for (XMLElement *meeting = meetings->FirstChildElement("meeting"); meeting; meeting = meeting->NextSiblingElement("meeting")) { XMLElement *meeting_id = meeting->FirstChildElement("meeting_id"); XMLElement *meeting_name = meeting->FirstChildElement("meeting_name"); XMLElement *start_time = meeting->FirstChildElement("start_time"); XMLElement *end_time = meeting->FirstChildElement("end_time"); XMLElement *meeting_conferrees = meeting->FirstChildElement("meeting_conferrees"); printf("meeting_id: %s\n", meeting_id->GetText()); printf("meeting_name: %s\n", meeting_name->GetText()); printf("start_time: %s\n", start_time->GetText()); printf("end_time: %s\n", end_time->GetText()); printf("conferreess:\n"); if (meeting_conferrees) { for (XMLElement *meeting_conferree = meeting_conferrees->FirstChildElement("meeting_conferree"); meeting_conferree; meeting_conferree = meeting_conferree->NextSiblingElement("meeting_conferree")) { XMLElement *user2_id = meeting_conferree->FirstChildElement("user_id"); XMLElement *user2_account = meeting_conferree->FirstChildElement("user_acount"); XMLElement *user2_name = meeting_conferree->FirstChildElement("user_name"); printf("user_id: %s\n", user2_id->GetText()); printf("user_account: %s\n", user2_account->GetText()); printf("user_name: %s\n", user2_name->GetText()); } } printf("\n"); } }
void XmlReader::xmlReadMsmServerInfo(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *msms = root->FirstChildElement("msms"); for (XMLElement *msm = msms->FirstChildElement("msm"); msm; msm = msm->NextSiblingElement("msm")) { XMLElement *msm_ip = msm->FirstChildElement("msm_ip"); XMLElement *msm_port = msm->FirstChildElement("msm_port"); printf("msm_ip: %s\n", msm_ip->GetText()); printf("msm_port: %s\n", msm_port->GetText()); } }
int example_3() { static const char* xml = "<?xml version=\"1.0\"?>" "<!DOCTYPE PLAY SYSTEM \"play.dtd\">" "<PLAY>" "<TITLE>A Midsummer Night's Dream</TITLE>" "</PLAY>"; XMLDocument doc; doc.Parse( xml ); XMLElement* titleElement = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" ); const char* title = titleElement->GetText(); printf( "Name of play (1): %s\n", title ); XMLText* textNode = titleElement->FirstChild()->ToText(); title = textNode->Value(); printf( "Name of play (2): %s\n", title ); return doc.ErrorID(); }
// TODO move this function to the constructor ? void Scene::loadSceneFromFile(const char* filename){ XMLDocument doc; doc.LoadFile(filename); // Check for errors in the XML if (doc.ErrorID() != 0) { doc.PrintError(); } XMLElement *music = doc.FirstChildElement("scene"); pathMusic = music->FirstChildElement("music")->GetText(); XMLElement *end = doc.FirstChildElement("scene"); if(end->FirstChildElement("end")) this->end = atoi(end->FirstChildElement("end")->GetText()); else this->end = 0; loadModels(doc); loadDialogues(doc); loadLights(doc); loadRoom(doc); }
void XmlReader::xmlReadTitleInfo(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *dev_id = root->FirstChildElement("dev_id"); XMLElement *user_account = root->FirstChildElement("user_acount"); XMLElement *vsp_url = root->FirstChildElement("vsp_url"); XMLElement *code = root->FirstChildElement("code"); XMLElement *msg = root->FirstChildElement("msg"); printf("dev_id: %s\n", dev_id->GetText()); printf("user_account: %s\n", user_account->GetText()); printf("vsp_url: %s\n", vsp_url->GetText());; printf("code: %s\n", code->GetText()); printf("msg: %s\n", msg->GetText()); printf("============================================\n"); }
int openFile(int argc, char **argv) { char cfgPath[256] = "./"; if(argc > 1) { strcat(cfgPath, argv[1]); strcat(cfgPath, "/"); } strcat(cfgPath, "config.xml"); cout << "Loading file from: " << cfgPath << endl; XMLDocument cfg; if(cfg.LoadFile(cfgPath) != XMLError(0)) { cerr << "Could not load file" << endl; cerr << "\t=> Does the file exists, or is it well writen?" << endl; return cfg.ErrorID(); } XMLElement *inFilesElement = cfg.FirstChildElement()->FirstChildElement("arquivosDeEntrada"); if(!inFilesElement) { cerr << "Could not find element: \"arquivosDeEntrada\"" << endl; return cfg.ErrorID(); } XMLElement *arenaFileElement = inFilesElement->FirstChildElement("arquivoDaArena"); if(!arenaFileElement) { cerr << "Could not find element: \"arquivoDaArena\"" << endl; return cfg.ErrorID(); } const char *arenaPath; arenaPath = arenaFileElement->Attribute("caminho"); if(!arenaPath) { cout << "Could not find arena file path. Exiting..." << endl; return -1; } //Considering that "~/" is at the begining of the path if(strstr(arenaPath, "~/") != NULL) { char *temp = getenv("HOME"); strcat(temp, arenaPath+1); arenaPath = temp; } char finalPath[1024]; finalPath[0] = '\0'; strcat(finalPath, arenaPath); strcat(finalPath, arenaFileElement->Attribute("nome")); strcat(finalPath, "."); strcat(finalPath, arenaFileElement->Attribute("tipo")); XMLElement *chopperInfoElement = cfg.FirstChildElement()->FirstChildElement("helicoptero"); if(!chopperInfoElement) { cerr << "Could not find element: \"helicoptero\"" << endl; return cfg.ErrorID(); } chopperInfoElement->QueryDoubleAttribute("velTiro", &g_bltSpeed); chopperInfoElement->QueryDoubleAttribute("velHelicoptero", &g_chpSpeed); XMLDocument cfgArena; if(cfgArena.LoadFile(finalPath) != XMLError(0)) { cerr << "Could not load arena config file" << endl; cerr << "\t=> Does the file exists, or is it well writen?" << endl; return cfgArena.ErrorID(); } XMLElement *svgElement = cfgArena.FirstChildElement("svg"); XMLElement *objectElement = svgElement->FirstChildElement(); do { Object *newObj; if(strstr(objectElement->Name(), "rect") != NULL) { int x, y, width, height, strW; const char *color, *strColor, *id; objectElement->QueryIntAttribute("x", &x); objectElement->QueryIntAttribute("y", &y); objectElement->QueryIntAttribute("width", &width); objectElement->QueryIntAttribute("height", &height); color = objectElement->Attribute("fill"); objectElement->QueryIntAttribute("stroke-width", &strW); strColor = objectElement->Attribute("stroke"); id = objectElement->Attribute("id"); double r = 0, g = 0, b = 0; double sr = 0, sg = 0, sb = 0; if(strstr(color, "red") != NULL) r = 1; if(strstr(color, "green") != NULL) g = 1; if(strstr(color, "blue") != NULL) b = 1; if(strstr(color, "white") != NULL) { r = 1; g = 1; b = 1; } if(strstr(color, "gray") != NULL) { r = 0.5; g = 0.5; b = 0.5; } if(strstr(strColor, "red") != NULL) sr = 1; if(strstr(strColor, "green") != NULL) sg = 1; if(strstr(strColor, "blue") != NULL) sb = 1; if(strstr(strColor, "white") != NULL) { sr = 1; sg = 1; sb = 1; } if(strstr(strColor, "grey") != NULL) { sr = 0.5; sg = 0.5; sb = 0.5; } newObj = new Rectangle(id, x+width/2, y+height/2, width, height, r, g, b, strW, sr, sg, sb); objects.push_back(newObj); } if(strstr(objectElement->Name(), "circle") != NULL) { int x, y, radius; const char *color, *id; objectElement->QueryIntAttribute("cx", &x); objectElement->QueryIntAttribute("cy", &y); objectElement->QueryIntAttribute("r", &radius); color = objectElement->Attribute("fill"); id = objectElement->Attribute("id"); double r = 0, g = 0, b = 0; if(strstr(color, "green") != NULL) { newObj = new Chopper(id, x, y, radius, g_chpSpeed, g_bltSpeed); objects.push_back(newObj); }else{ if(strstr(color, "red") != NULL) r = 1; if(strstr(color, "blue") != NULL) b = 1; if(strstr(color, "white") != NULL) { r = 1; g = 1; b = 1; } if(strstr(color, "grey") != NULL) { r = 0.5; g = 0.5; b = 0.5; } newObj = new Circle(id, x, y, radius, r, g, b); objects.push_back(newObj); } } objectElement = objectElement->NextSiblingElement(); }while(objectElement != NULL); return cfg.ErrorID(); }
int main( int argc, const char ** argv ) { #if defined( _MSC_VER ) && defined( DEBUG ) _CrtMemCheckpoint( &startMemState ); #endif #if defined(_MSC_VER) || defined(MINGW32) || defined(__MINGW32__) #if defined __MINGW64_VERSION_MAJOR && defined __MINGW64_VERSION_MINOR //MINGW64: both 32 and 64-bit mkdir( "resources/out/" ); #else _mkdir( "resources/out/" ); #endif #else mkdir( "resources/out/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); #endif if ( argc > 1 ) { XMLDocument* doc = new XMLDocument(); clock_t startTime = clock(); doc->LoadFile( argv[1] ); clock_t loadTime = clock(); int errorID = doc->ErrorID(); delete doc; doc = 0; clock_t deleteTime = clock(); printf( "Test file '%s' loaded. ErrorID=%d\n", argv[1], errorID ); if ( !errorID ) { printf( "Load time=%u\n", (unsigned)(loadTime - startTime) ); printf( "Delete time=%u\n", (unsigned)(deleteTime - loadTime) ); printf( "Total time=%u\n", (unsigned)(deleteTime - startTime) ); } exit(0); } FILE* fp = fopen( "resources/dream.xml", "r" ); if ( !fp ) { printf( "Error opening test file 'dream.xml'.\n" "Is your working directory the same as where \n" "the xmltest.cpp and dream.xml file are?\n\n" #if defined( _MSC_VER ) "In windows Visual Studio you may need to set\n" "Properties->Debugging->Working Directory to '..'\n" #endif ); exit( 1 ); } fclose( fp ); XMLTest( "Example-1", 0, example_1() ); XMLTest( "Example-2", 0, example_2() ); XMLTest( "Example-3", 0, example_3() ); XMLTest( "Example-4", true, example_4() ); /* ------ Example 2: Lookup information. ---- */ { static const char* test[] = { "<element />", "<element></element>", "<element><subelement/></element>", "<element><subelement></subelement></element>", "<element><subelement><subsub/></subelement></element>", "<!--comment beside elements--><element><subelement></subelement></element>", "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>", "<element attrib1='foo' attrib2=\"bar\" ></element>", "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>", "<element>Text inside element.</element>", "<element><b></b></element>", "<element>Text inside and <b>bolded</b> in the element.</element>", "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>", "<element>This & That.</element>", "<element attrib='This<That' />", 0 }; for( int i=0; test[i]; ++i ) { XMLDocument doc; doc.Parse( test[i] ); doc.Print(); printf( "----------------------------------------------\n" ); } } #if 1 { static const char* test = "<!--hello world\n" " line 2\r" " line 3\r\n" " line 4\n\r" " line 5\r-->"; XMLDocument doc; doc.Parse( test ); doc.Print(); } { static const char* test = "<element>Text before.</element>"; XMLDocument doc; doc.Parse( test ); XMLElement* root = doc.FirstChildElement(); XMLElement* newElement = doc.NewElement( "Subelement" ); root->InsertEndChild( newElement ); doc.Print(); } { XMLDocument* doc = new XMLDocument(); static const char* test = "<element><sub/></element>"; doc->Parse( test ); delete doc; } { // Test: Programmatic DOM // Build: // <element> // <!--comment--> // <sub attrib="1" /> // <sub attrib="2" /> // <sub attrib="3" >& Text!</sub> // <element> XMLDocument* doc = new XMLDocument(); XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) ); XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) }; for( int i=0; i<3; ++i ) { sub[i]->SetAttribute( "attrib", i ); } element->InsertEndChild( sub[2] ); XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) ); element->InsertAfterChild( comment, sub[0] ); element->InsertAfterChild( sub[0], sub[1] ); sub[2]->InsertFirstChild( doc->NewText( "& Text!" )); doc->Print(); XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() ); XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) ); XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) ); XMLTest( "Programmatic DOM", "& Text!", doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() ); // And now deletion: element->DeleteChild( sub[2] ); doc->DeleteNode( comment ); element->FirstChildElement()->SetAttribute( "attrib", true ); element->LastChildElement()->DeleteAttribute( "attrib" ); XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) ); int value = 10; int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value ); XMLTest( "Programmatic DOM", result, (int)XML_NO_ATTRIBUTE ); XMLTest( "Programmatic DOM", value, 10 ); doc->Print(); { XMLPrinter streamer; doc->Print( &streamer ); printf( "%s", streamer.CStr() ); } { XMLPrinter streamer( 0, true ); doc->Print( &streamer ); XMLTest( "Compact mode", "<element><sub attrib=\"1\"/><sub/></element>", streamer.CStr(), false ); } doc->SaveFile( "./resources/out/pretty.xml" ); doc->SaveFile( "./resources/out/compact.xml", true ); delete doc; } { // Test: Dream // XML1 : 1,187,569 bytes in 31,209 allocations // XML2 : 469,073 bytes in 323 allocations //int newStart = gNew; XMLDocument doc; doc.LoadFile( "resources/dream.xml" ); doc.SaveFile( "resources/out/dreamout.xml" ); doc.PrintError(); XMLTest( "Dream", "xml version=\"1.0\"", doc.FirstChild()->ToDeclaration()->Value() ); XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false ); XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"", doc.FirstChild()->NextSibling()->ToUnknown()->Value() ); XMLTest( "Dream", "And Robin shall restore amends.", doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); XMLTest( "Dream", "And Robin shall restore amends.", doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); XMLDocument doc2; doc2.LoadFile( "resources/out/dreamout.xml" ); XMLTest( "Dream-out", "xml version=\"1.0\"", doc2.FirstChild()->ToDeclaration()->Value() ); XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false ); XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"", doc2.FirstChild()->NextSibling()->ToUnknown()->Value() ); XMLTest( "Dream-out", "And Robin shall restore amends.", doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); //gNewTotal = gNew - newStart; } { const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n" "<passages count=\"006\" formatversion=\"20020620\">\n" " <wrong error>\n" "</passages>"; XMLDocument doc; doc.Parse( error ); XMLTest( "Bad XML", doc.ErrorID(), XML_ERROR_PARSING_ATTRIBUTE ); } { const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />"; XMLDocument doc; doc.Parse( str ); XMLElement* ele = doc.FirstChildElement(); int iVal, result; double dVal; result = ele->QueryDoubleAttribute( "attr0", &dVal ); XMLTest( "Query attribute: int as double", result, (int)XML_NO_ERROR ); XMLTest( "Query attribute: int as double", (int)dVal, 1 ); result = ele->QueryDoubleAttribute( "attr1", &dVal ); XMLTest( "Query attribute: double as double", result, (int)XML_NO_ERROR ); XMLTest( "Query attribute: double as double", (int)dVal, 2 ); result = ele->QueryIntAttribute( "attr1", &iVal ); XMLTest( "Query attribute: double as int", result, (int)XML_NO_ERROR ); XMLTest( "Query attribute: double as int", iVal, 2 ); result = ele->QueryIntAttribute( "attr2", &iVal ); XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE ); result = ele->QueryIntAttribute( "bar", &iVal ); XMLTest( "Query attribute: does not exist", result, (int)XML_NO_ATTRIBUTE ); } { const char* str = "<doc/>"; XMLDocument doc; doc.Parse( str ); XMLElement* ele = doc.FirstChildElement(); int iVal, iVal2; double dVal, dVal2; ele->SetAttribute( "str", "strValue" ); ele->SetAttribute( "int", 1 ); ele->SetAttribute( "double", -1.0 ); const char* cStr = ele->Attribute( "str" ); ele->QueryIntAttribute( "int", &iVal ); ele->QueryDoubleAttribute( "double", &dVal ); ele->QueryAttribute( "int", &iVal2 ); ele->QueryAttribute( "double", &dVal2 ); XMLTest( "Attribute match test", ele->Attribute( "str", "strValue" ), "strValue" ); XMLTest( "Attribute round trip. c-string.", "strValue", cStr ); XMLTest( "Attribute round trip. int.", 1, iVal ); XMLTest( "Attribute round trip. double.", -1, (int)dVal ); XMLTest( "Alternate query", true, iVal == iVal2 ); XMLTest( "Alternate query", true, dVal == dVal2 ); } { XMLDocument doc; doc.LoadFile( "resources/utf8test.xml" ); // Get the attribute "value" from the "Russian" element and check it. XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" ); const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 }; XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) ); const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U, 0xd1U, 0x81U, 0xd1U, 0x81U, 0xd0U, 0xbaU, 0xd0U, 0xb8U, 0xd0U, 0xb9U, 0 }; const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>"; XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText(); XMLTest( "UTF-8: Browsing russian element name.", russianText, text->Value() ); // Now try for a round trip. doc.SaveFile( "resources/out/utf8testout.xml" ); // Check the round trip. int okay = 0; FILE* saved = fopen( "resources/out/utf8testout.xml", "r" ); FILE* verify = fopen( "resources/utf8testverify.xml", "r" ); if ( saved && verify ) { okay = 1; char verifyBuf[256]; while ( fgets( verifyBuf, 256, verify ) ) { char savedBuf[256]; fgets( savedBuf, 256, saved ); NullLineEndings( verifyBuf ); NullLineEndings( savedBuf ); if ( strcmp( verifyBuf, savedBuf ) ) { printf( "verify:%s<\n", verifyBuf ); printf( "saved :%s<\n", savedBuf ); okay = 0; break; } } } if ( saved ) fclose( saved ); if ( verify ) fclose( verify ); XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay ); } // --------GetText()----------- { const char* str = "<foo>This is text</foo>"; XMLDocument doc; doc.Parse( str ); const XMLElement* element = doc.RootElement(); XMLTest( "GetText() normal use.", "This is text", element->GetText() ); str = "<foo><b>This is text</b></foo>"; doc.Parse( str ); element = doc.RootElement(); XMLTest( "GetText() contained element.", element->GetText() == 0, true ); } // ---------- CDATA --------------- { const char* str = "<xmlElement>" "<![CDATA[" "I am > the rules!\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; XMLDocument doc; doc.Parse( str ); doc.Print(); XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), "I am > the rules!\n...since I make symbolic puns", false ); } // ----------- CDATA ------------- { const char* str = "<xmlElement>" "<![CDATA[" "<b>I am > the rules!</b>\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; XMLDocument doc; doc.Parse( str ); doc.Print(); XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), "<b>I am > the rules!</b>\n...since I make symbolic puns", false ); } // InsertAfterChild causes crash. { // InsertBeforeChild and InsertAfterChild causes crash. XMLDocument doc; XMLElement* parent = doc.NewElement( "Parent" ); doc.InsertFirstChild( parent ); XMLElement* childText0 = doc.NewElement( "childText0" ); XMLElement* childText1 = doc.NewElement( "childText1" ); XMLNode* childNode0 = parent->InsertEndChild( childText0 ); XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 ); XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true ); } { // Entities not being written correctly. // From Lynn Allen const char* passages = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<passages count=\"006\" formatversion=\"20020620\">" "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright ©.\"> </psg>" "</passages>"; XMLDocument doc; doc.Parse( passages ); XMLElement* psg = doc.RootElement()->FirstChildElement(); const char* context = psg->Attribute( "context" ); const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9."; XMLTest( "Entity transformation: read. ", expected, context, true ); FILE* textfile = fopen( "resources/out/textfile.txt", "w" ); if ( textfile ) { XMLPrinter streamer( textfile ); psg->Accept( &streamer ); fclose( textfile ); } textfile = fopen( "resources/out/textfile.txt", "r" ); TIXMLASSERT( textfile ); if ( textfile ) { char buf[ 1024 ]; fgets( buf, 1024, textfile ); XMLTest( "Entity transformation: write. ", "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright \xC2\xA9.\"/>\n", buf, false ); fclose( textfile ); } } { // Suppress entities. const char* passages = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<passages count=\"006\" formatversion=\"20020620\">" "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'.\">Crazy &ttk;</psg>" "</passages>"; XMLDocument doc( false ); doc.Parse( passages ); XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ), "Line 5 has "quotation marks" and 'apostrophe marks'." ); XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(), "Crazy &ttk;" ); doc.Print(); } { const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>"; XMLDocument doc; doc.Parse( test ); XMLTest( "dot in names", doc.Error(), false ); XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" ); XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" ); } { const char* test = "<element><Name>1.1 Start easy ignore fin thickness
</Name></element>"; XMLDocument doc; doc.Parse( test ); XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText(); XMLTest( "Entity with one digit.", text->Value(), "1.1 Start easy ignore fin thickness\n", false ); } { // DOCTYPE not preserved (950171) // const char* doctype = "<?xml version=\"1.0\" ?>" "<!DOCTYPE PLAY SYSTEM 'play.dtd'>" "<!ELEMENT title (#PCDATA)>" "<!ELEMENT books (title,authors)>" "<element />"; XMLDocument doc; doc.Parse( doctype ); doc.SaveFile( "resources/out/test7.xml" ); doc.DeleteChild( doc.RootElement() ); doc.LoadFile( "resources/out/test7.xml" ); doc.Print(); const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown(); XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() ); } { // Comments do not stream out correctly. const char* doctype = "<!-- Somewhat<evil> -->"; XMLDocument doc; doc.Parse( doctype ); XMLComment* comment = doc.FirstChild()->ToComment(); XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() ); } { // Double attributes const char* doctype = "<element attr='red' attr='blue' />"; XMLDocument doc; doc.Parse( doctype ); XMLTest( "Parsing repeated attributes.", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues) doc.PrintError(); } { // Embedded null in stream. const char* doctype = "<element att\0r='red' attr='blue' />"; XMLDocument doc; doc.Parse( doctype ); XMLTest( "Embedded null throws error.", true, doc.Error() ); } { // Empty documents should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717 const char* str = " "; XMLDocument doc; doc.Parse( str ); XMLTest( "Empty document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() ); } { // Low entities XMLDocument doc; doc.Parse( "<test></test>" ); const char result[] = { 0x0e, 0 }; XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result ); doc.Print(); } { // Attribute values with trailing quotes not handled correctly XMLDocument doc; doc.Parse( "<foo attribute=bar\" />" ); XMLTest( "Throw error with bad end quotes.", doc.Error(), true ); } { // [ 1663758 ] Failure to report error on bad XML XMLDocument xml; xml.Parse("<x>"); XMLTest("Missing end tag at end of input", xml.Error(), true); xml.Parse("<x> "); XMLTest("Missing end tag with trailing whitespace", xml.Error(), true); xml.Parse("<x></y>"); XMLTest("Mismatched tags", xml.ErrorID(), XML_ERROR_MISMATCHED_ELEMENT); } { // [ 1475201 ] TinyXML parses entities in comments XMLDocument xml; xml.Parse("<!-- declarations for <head> & <body> -->" "<!-- far & away -->" ); XMLNode* e0 = xml.FirstChild(); XMLNode* e1 = e0->NextSibling(); XMLComment* c0 = e0->ToComment(); XMLComment* c1 = e1->ToComment(); XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); XMLTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); } { XMLDocument xml; xml.Parse( "<Parent>" "<child1 att=''/>" "<!-- With this comment, child2 will not be parsed! -->" "<child2 att=''/>" "</Parent>" ); xml.Print(); int count = 0; for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild(); ele; ele = ele->NextSibling() ) { ++count; } XMLTest( "Comments iterate correctly.", 3, count ); } { // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well. unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl"; buf[60] = 239; buf[61] = 0; XMLDocument doc; doc.Parse( (const char*)buf); } { // bug 1827248 Error while parsing a little bit malformed file // Actually not malformed - should work. XMLDocument xml; xml.Parse( "<attributelist> </attributelist >" ); XMLTest( "Handle end tag whitespace", false, xml.Error() ); } { // This one must not result in an infinite loop XMLDocument xml; xml.Parse( "<infinite>loop" ); XMLTest( "Infinite loop test.", true, true ); } #endif { const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>"; XMLDocument doc; doc.Parse( pub ); XMLDocument clone; for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) { XMLNode* copy = node->ShallowClone( &clone ); clone.InsertEndChild( copy ); } clone.Print(); int count=0; const XMLNode* a=clone.FirstChild(); const XMLNode* b=doc.FirstChild(); for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) { ++count; XMLTest( "Clone and Equal", true, a->ShallowEqual( b )); } XMLTest( "Clone and Equal", 4, count ); } { // This shouldn't crash. XMLDocument doc; if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" )) { doc.PrintError(); } XMLTest( "Error in snprinf handling.", true, doc.Error() ); } { // Attribute ordering. static const char* xml = "<element attrib1=\"1\" attrib2=\"2\" attrib3=\"3\" />"; XMLDocument doc; doc.Parse( xml ); XMLElement* ele = doc.FirstChildElement(); const XMLAttribute* a = ele->FirstAttribute(); XMLTest( "Attribute order", "1", a->Value() ); a = a->Next(); XMLTest( "Attribute order", "2", a->Value() ); a = a->Next(); XMLTest( "Attribute order", "3", a->Value() ); XMLTest( "Attribute order", "attrib3", a->Name() ); ele->DeleteAttribute( "attrib2" ); a = ele->FirstAttribute(); XMLTest( "Attribute order", "1", a->Value() ); a = a->Next(); XMLTest( "Attribute order", "3", a->Value() ); ele->DeleteAttribute( "attrib1" ); ele->DeleteAttribute( "attrib3" ); XMLTest( "Attribute order (empty)", false, ele->FirstAttribute() ? true : false ); } { // Make sure an attribute with a space in it succeeds. static const char* xml0 = "<element attribute1= \"Test Attribute\"/>"; static const char* xml1 = "<element attribute1 =\"Test Attribute\"/>"; static const char* xml2 = "<element attribute1 = \"Test Attribute\"/>"; XMLDocument doc0; doc0.Parse( xml0 ); XMLDocument doc1; doc1.Parse( xml1 ); XMLDocument doc2; doc2.Parse( xml2 ); XMLElement* ele = 0; ele = doc0.FirstChildElement(); XMLTest( "Attribute with space #1", "Test Attribute", ele->Attribute( "attribute1" ) ); ele = doc1.FirstChildElement(); XMLTest( "Attribute with space #2", "Test Attribute", ele->Attribute( "attribute1" ) ); ele = doc2.FirstChildElement(); XMLTest( "Attribute with space #3", "Test Attribute", ele->Attribute( "attribute1" ) ); } { // Make sure we don't go into an infinite loop. static const char* xml = "<doc><element attribute='attribute'/><element attribute='attribute'/></doc>"; XMLDocument doc; doc.Parse( xml ); XMLElement* ele0 = doc.FirstChildElement()->FirstChildElement(); XMLElement* ele1 = ele0->NextSiblingElement(); bool equal = ele0->ShallowEqual( ele1 ); XMLTest( "Infinite loop in shallow equal.", true, equal ); } // -------- Handles ------------ { static const char* xml = "<element attrib='bar'><sub>Text</sub></element>"; XMLDocument doc; doc.Parse( xml ); XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, mutable", ele->Value(), "sub" ); XMLHandle docH( doc ); ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement(); XMLTest( "Handle, dne, mutable", false, ele != 0 ); } { static const char* xml = "<element attrib='bar'><sub>Text</sub></element>"; XMLDocument doc; doc.Parse( xml ); XMLConstHandle docH( doc ); const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement(); XMLTest( "Handle, success, const", ele->Value(), "sub" ); ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement(); XMLTest( "Handle, dne, const", false, ele != 0 ); } { // Default Declaration & BOM XMLDocument doc; doc.InsertEndChild( doc.NewDeclaration() ); doc.SetBOM( true ); XMLPrinter printer; doc.Print( &printer ); static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; XMLTest( "BOM and default declaration", printer.CStr(), result, false ); XMLTest( "CStrSize", printer.CStrSize(), 42, false ); } { const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>"; XMLDocument doc; doc.Parse( xml ); XMLTest( "Ill formed XML", true, doc.Error() ); } // QueryXYZText { const char* xml = "<point> <x>1.2</x> <y>1</y> <z>38</z> <valid>true</valid> </point>"; XMLDocument doc; doc.Parse( xml ); const XMLElement* pointElement = doc.RootElement(); int intValue = 0; unsigned unsignedValue = 0; float floatValue = 0; double doubleValue = 0; bool boolValue = false; pointElement->FirstChildElement( "y" )->QueryIntText( &intValue ); pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue ); pointElement->FirstChildElement( "x" )->QueryFloatText( &floatValue ); pointElement->FirstChildElement( "x" )->QueryDoubleText( &doubleValue ); pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue ); XMLTest( "QueryIntText", intValue, 1, false ); XMLTest( "QueryUnsignedText", unsignedValue, (unsigned)1, false ); XMLTest( "QueryFloatText", floatValue, 1.2f, false ); XMLTest( "QueryDoubleText", doubleValue, 1.2, false ); XMLTest( "QueryBoolText", boolValue, true, false ); } { const char* xml = "<element><_sub/><:sub/><sub:sub/><sub-sub/></element>"; XMLDocument doc; doc.Parse( xml ); XMLTest( "Non-alpha element lead letter parses.", doc.Error(), false ); } { const char* xml = "<element _attr1=\"foo\" :attr2=\"bar\"></element>"; XMLDocument doc; doc.Parse( xml ); XMLTest("Non-alpha attribute lead character parses.", doc.Error(), false); } { const char* xml = "<3lement></3lement>"; XMLDocument doc; doc.Parse( xml ); XMLTest("Element names with lead digit fail to parse.", doc.Error(), true); } { const char* xml = "<element/>WOA THIS ISN'T GOING TO PARSE"; XMLDocument doc; doc.Parse( xml, 10 ); XMLTest( "Set length of incoming data", doc.Error(), false ); } { XMLDocument doc; doc.LoadFile( "resources/dream.xml" ); doc.Clear(); XMLTest( "Document Clear()'s", doc.NoChildren(), true ); } // ----------- Whitespace ------------ { const char* xml = "<element>" "<a> This \nis ' text ' </a>" "<b> This is ' text ' \n</b>" "<c>This is ' \n\n text '</c>" "</element>"; XMLDocument doc( true, COLLAPSE_WHITESPACE ); doc.Parse( xml ); const XMLElement* element = doc.FirstChildElement(); for( const XMLElement* parent = element->FirstChildElement(); parent; parent = parent->NextSiblingElement() ) { XMLTest( "Whitespace collapse", "This is ' text '", parent->GetText() ); } } #if 0 { // Passes if assert doesn't fire. XMLDocument xmlDoc; xmlDoc.NewDeclaration(); xmlDoc.NewComment("Configuration file"); XMLElement *root = xmlDoc.NewElement("settings"); root->SetAttribute("version", 2); } #endif { const char* xml = "<element> </element>"; XMLDocument doc( true, COLLAPSE_WHITESPACE ); doc.Parse( xml ); XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() ); } #if 0 // the question being explored is what kind of print to use: // https://github.com/leethomason/tinyxml2/issues/63 { const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9'/>"; XMLDocument doc; doc.Parse( xml ); doc.FirstChildElement()->SetAttribute( "attrA", 123456789.123456789 ); doc.FirstChildElement()->SetAttribute( "attrB", 1.001e9 ); doc.Print(); } #endif { // An assert should not fire. const char* xml = "<element/>"; XMLDocument doc; doc.Parse( xml ); XMLElement* ele = doc.NewElement( "unused" ); // This will get cleaned up with the 'doc' going out of scope. XMLTest( "Tracking unused elements", true, ele != 0, false ); } { const char* xml = "<parent><child>abc</child></parent>"; XMLDocument doc; doc.Parse( xml ); XMLElement* ele = doc.FirstChildElement( "parent")->FirstChildElement( "child"); XMLPrinter printer; ele->Accept( &printer ); XMLTest( "Printing of sub-element", "<child>abc</child>\n", printer.CStr(), false ); } { XMLDocument doc; XMLError error = doc.LoadFile( "resources/empty.xml" ); XMLTest( "Loading an empty file", XML_ERROR_EMPTY_DOCUMENT, error ); } { // BOM preservation static const char* xml_bom_preservation = "\xef\xbb\xbf<element/>\n"; { XMLDocument doc; XMLTest( "BOM preservation (parse)", XML_NO_ERROR, doc.Parse( xml_bom_preservation ), false ); XMLPrinter printer; doc.Print( &printer ); XMLTest( "BOM preservation (compare)", xml_bom_preservation, printer.CStr(), false, true ); doc.SaveFile( "resources/bomtest.xml" ); } { XMLDocument doc; doc.LoadFile( "resources/bomtest.xml" ); XMLTest( "BOM preservation (load)", true, doc.HasBOM(), false ); XMLPrinter printer; doc.Print( &printer ); XMLTest( "BOM preservation (compare)", xml_bom_preservation, printer.CStr(), false, true ); } } { // Insertion with Removal const char* xml = "<?xml version=\"1.0\" ?>" "<root>" "<one>" "<subtree>" "<elem>element 1</elem>text<!-- comment -->" "</subtree>" "</one>" "<two/>" "</root>"; const char* xmlInsideTwo = "<?xml version=\"1.0\" ?>" "<root>" "<one/>" "<two>" "<subtree>" "<elem>element 1</elem>text<!-- comment -->" "</subtree>" "</two>" "</root>"; const char* xmlAfterOne = "<?xml version=\"1.0\" ?>" "<root>" "<one/>" "<subtree>" "<elem>element 1</elem>text<!-- comment -->" "</subtree>" "<two/>" "</root>"; const char* xmlAfterTwo = "<?xml version=\"1.0\" ?>" "<root>" "<one/>" "<two/>" "<subtree>" "<elem>element 1</elem>text<!-- comment -->" "</subtree>" "</root>"; XMLDocument doc; doc.Parse( xml ); XMLElement* subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); XMLElement* two = doc.RootElement()->FirstChildElement("two"); two->InsertFirstChild(subtree); XMLPrinter printer1( 0, true ); doc.Accept( &printer1 ); XMLTest( "Move node from within <one> to <two>", xmlInsideTwo, printer1.CStr()); doc.Parse( xml ); subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); two = doc.RootElement()->FirstChildElement("two"); doc.RootElement()->InsertAfterChild(two, subtree); XMLPrinter printer2( 0, true ); doc.Accept( &printer2 ); XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer2.CStr(), false ); doc.Parse( xml ); XMLNode* one = doc.RootElement()->FirstChildElement("one"); subtree = one->FirstChildElement("subtree"); doc.RootElement()->InsertAfterChild(one, subtree); XMLPrinter printer3( 0, true ); doc.Accept( &printer3 ); XMLTest( "Move node from within <one> after <one>", xmlAfterOne, printer3.CStr(), false ); doc.Parse( xml ); subtree = doc.RootElement()->FirstChildElement("one")->FirstChildElement("subtree"); two = doc.RootElement()->FirstChildElement("two"); doc.RootElement()->InsertEndChild(subtree); XMLPrinter printer4( 0, true ); doc.Accept( &printer4 ); XMLTest( "Move node from within <one> after <two>", xmlAfterTwo, printer4.CStr(), false ); } // ----------- Performance tracking -------------- { #if defined( _MSC_VER ) __int64 start, end, freq; QueryPerformanceFrequency( (LARGE_INTEGER*) &freq ); #endif FILE* fp = fopen( "resources/dream.xml", "r" ); fseek( fp, 0, SEEK_END ); long size = ftell( fp ); fseek( fp, 0, SEEK_SET ); char* mem = new char[size+1]; fread( mem, size, 1, fp ); fclose( fp ); mem[size] = 0; #if defined( _MSC_VER ) QueryPerformanceCounter( (LARGE_INTEGER*) &start ); #else clock_t cstart = clock(); #endif static const int COUNT = 10; for( int i=0; i<COUNT; ++i ) { XMLDocument doc; doc.Parse( mem ); } #if defined( _MSC_VER ) QueryPerformanceCounter( (LARGE_INTEGER*) &end ); #else clock_t cend = clock(); #endif delete [] mem; static const char* note = #ifdef DEBUG "DEBUG"; #else "Release"; #endif #if defined( _MSC_VER ) printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, 1000.0 * (double)(end-start) / ( (double)freq * (double)COUNT) ); #else printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, (double)(cend - cstart)/(double)COUNT ); #endif } #if defined( _MSC_VER ) && defined( DEBUG ) _CrtMemCheckpoint( &endMemState ); //_CrtMemDumpStatistics( &endMemState ); _CrtMemState diffMemState; _CrtMemDifference( &diffMemState, &startMemState, &endMemState ); _CrtMemDumpStatistics( &diffMemState ); //printf( "new total=%d\n", gNewTotal ); #endif printf ("\nPass %d, Fail %d\n", gPass, gFail); return gFail; }
bool TilemapLoader::LoadTilemap(const string _path, Tilemap& _tilemap) { // Temporary map object Tilemap temp_map; // Load TMX file in TinyXML XMLDocument doc; doc.LoadFile(_path.c_str()); // Check for error in parsing if (doc.Error()) { cout << "XML Parsing Error: " << doc.ErrorID() << endl; return false; } // Find the map element const XMLElement* map_element = doc.FirstChildElement("map"); if (!CheckPointer(map_element, "Couldn't locate map element in map file")) return false; // Load all of the basic map data map_element->QueryFloatAttribute("version", &temp_map.version); map_element->QueryIntAttribute("width", &temp_map.map_dimensions.x); map_element->QueryIntAttribute("height", &temp_map.map_dimensions.y); map_element->QueryIntAttribute("tilewidth", &temp_map.tile_dimensions.x); map_element->QueryIntAttribute("tileheight", &temp_map.tile_dimensions.y); // Load the orientation of the tile map. Only orthogonal // is supported currently. string orient_str = map_element->Attribute("orientation"); if (orient_str == "orthogonal") temp_map.orientation = SFTILE_ORIENT_ORTHOGONAL; else { cout << "SfTileEngine currently only supports orthogonal tile maps." << endl; temp_map.orientation = SFTILE_ORIENT_UNSUPPORTED; return false; } // Parse the tilesets in the tile map. const XMLElement* tileset_element = map_element->FirstChildElement("tileset"); while (tileset_element) { if (!ParseTileset(tileset_element, temp_map.tileset)) { cout << "Failed to parse tileset" << endl; return false; } tileset_element = tileset_element->NextSiblingElement("tileset"); } // Don't let your pointer dangle... That's gross. tileset_element = nullptr; // Parse all layers: tile, object, image const XMLElement* layer_element = map_element->FirstChildElement(); while (layer_element) { string name = layer_element->Name(); if (name == "layer") { TileLayer temp_tile_layer; if (!ParseTileLayer(layer_element, temp_tile_layer)) { cout << "Failed to parse tile layer" << endl; return false; } else temp_map.layers.push_back(unique_ptr<TileLayer>(new TileLayer(temp_tile_layer))); } else if (name == "objectgroup") { ObjectLayer temp_object_layer; if (!ParseObjectLayer(layer_element, temp_object_layer)) { cout << "Failed to parse object layer" << endl; return false; } else temp_map.layers.push_back(unique_ptr<ObjectLayer>(new ObjectLayer(temp_object_layer))); } /*else if (layer_element->Name() == "imagelayer") { ImageLayer temp_image_layer; if (!ParseImageLayer(layer_element, temp_image_layer)) { cout << "Failed to parse image layer" << endl; return false; } else temp_map.layers.push_back(unique_ptr<ImageLayer>(new ImageLayer(temp_image_layer))); }*/ layer_element = layer_element->NextSiblingElement(); } layer_element = nullptr; /* // Parse the tile layers const XMLElement* tile_layer_element = map_element->FirstChildElement("layer"); while (tile_layer_element) { TileLayer temp_tile_layer; if (!ParseTileLayer(tile_layer_element, temp_tile_layer)) { cout << "Failed to parse tile layer" << endl; return false; } else { temp_map.layers.push_back(unique_ptr<TileLayer>(new TileLayer(temp_tile_layer))); } tile_layer_element = tile_layer_element->NextSiblingElement("layer"); } tile_layer_element = nullptr;*/ /// Parse the object layers (object groups) /*const XMLElement* object_layer_element = map_element->FirstChildElement("objectgroup"); while (object_layer_element) { ObjectLayer temp_object_layer; if (!ParseObjectLayer(object_layer_element, temp_object_layer)) { cout << "Failed to parse object layer" << endl; return false; } else { temp_map.layers.push_back(temp_object_layer); } object_layer_element = object_layer_element->NextSiblingElement("objectgroup"); } object_layer_element = nullptr;*/ _tilemap = std::move(temp_map); return true; }
int main( int /*argc*/, const char ** /*argv*/ ) { #if defined( _MSC_VER ) && defined( DEBUG ) _CrtMemCheckpoint( &startMemState ); #endif #if defined(_MSC_VER) #pragma warning ( push ) #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #endif FILE* fp = fopen( "dream.xml", "r" ); if ( !fp ) { printf( "Error opening test file 'dream.xml'.\n" "Is your working directory the same as where \n" "the xmltest.cpp and dream.xml file are?\n\n" #if defined( _MSC_VER ) "In windows Visual Studio you may need to set\n" "Properties->Debugging->Working Directory to '..'\n" #endif ); exit( 1 ); } fclose( fp ); #if defined(_MSC_VER) #pragma warning ( pop ) #endif /* ------ Example 1: Load and parse an XML file. ---- */ { XMLDocument doc; doc.LoadFile( "dream.xml" ); } /* ------ Example 2: Lookup information. ---- */ { XMLDocument doc; doc.LoadFile( "dream.xml" ); // Structure of the XML file: // - Element "PLAY" the root Element // - - Element "TITLE" child of the root PLAY Element // - - - Text child of the TITLE Element // Navigate to the title, using the convenience function, with a dangerous lack of error checking. const char* title = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->GetText(); printf( "Name of play (1): %s\n", title ); // Text is just another Node to TinyXML-2. The more general way to get to the XMLText: XMLText* textNode = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" )->FirstChild()->ToText(); title = textNode->Value(); printf( "Name of play (2): %s\n", title ); } { static const char* test[] = { "<element />", "<element></element>", "<element><subelement/></element>", "<element><subelement></subelement></element>", "<element><subelement><subsub/></subelement></element>", "<!--comment beside elements--><element><subelement></subelement></element>", "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>", "<element attrib1='foo' attrib2=\"bar\" ></element>", "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>", "<element>Text inside element.</element>", "<element><b></b></element>", "<element>Text inside and <b>bolded</b> in the element.</element>", "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>", "<element>This & That.</element>", "<element attrib='This<That' />", 0 }; for( int i=0; test[i]; ++i ) { XMLDocument doc; doc.Parse( test[i] ); doc.Print(); printf( "----------------------------------------------\n" ); } } #if 1 { static const char* test = "<!--hello world\n" " line 2\r" " line 3\r\n" " line 4\n\r" " line 5\r-->"; XMLDocument doc; doc.Parse( test ); doc.Print(); } { static const char* test = "<element>Text before.</element>"; XMLDocument doc; doc.Parse( test ); XMLElement* root = doc.FirstChildElement(); XMLElement* newElement = doc.NewElement( "Subelement" ); root->InsertEndChild( newElement ); doc.Print(); } { XMLDocument* doc = new XMLDocument(); static const char* test = "<element><sub/></element>"; doc->Parse( test ); delete doc; } { // Test: Programmatic DOM // Build: // <element> // <!--comment--> // <sub attrib="1" /> // <sub attrib="2" /> // <sub attrib="3" >& Text!</sub> // <element> XMLDocument* doc = new XMLDocument(); XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) ); XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) }; for( int i=0; i<3; ++i ) { sub[i]->SetAttribute( "attrib", i ); } element->InsertEndChild( sub[2] ); XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) ); element->InsertAfterChild( comment, sub[0] ); element->InsertAfterChild( sub[0], sub[1] ); sub[2]->InsertFirstChild( doc->NewText( "& Text!" )); doc->Print(); XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() ); XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) ); XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) ); XMLTest( "Programmatic DOM", "& Text!", doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() ); // And now deletion: element->DeleteChild( sub[2] ); doc->DeleteNode( comment ); element->FirstChildElement()->SetAttribute( "attrib", true ); element->LastChildElement()->DeleteAttribute( "attrib" ); XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) ); int value = 10; int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value ); XMLTest( "Programmatic DOM", result, XML_NO_ATTRIBUTE ); XMLTest( "Programmatic DOM", value, 10 ); doc->Print(); XMLPrinter streamer; doc->Print( &streamer ); printf( "%s", streamer.CStr() ); delete doc; } { // Test: Dream // XML1 : 1,187,569 bytes in 31,209 allocations // XML2 : 469,073 bytes in 323 allocations //int newStart = gNew; XMLDocument doc; doc.LoadFile( "dream.xml" ); doc.SaveFile( "dreamout.xml" ); doc.PrintError(); XMLTest( "Dream", "xml version=\"1.0\"", doc.FirstChild()->ToDeclaration()->Value() ); XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false ); XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"", doc.FirstChild()->NextSibling()->ToUnknown()->Value() ); XMLTest( "Dream", "And Robin shall restore amends.", doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); XMLTest( "Dream", "And Robin shall restore amends.", doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); XMLDocument doc2; doc2.LoadFile( "dreamout.xml" ); XMLTest( "Dream-out", "xml version=\"1.0\"", doc2.FirstChild()->ToDeclaration()->Value() ); XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false ); XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"", doc2.FirstChild()->NextSibling()->ToUnknown()->Value() ); XMLTest( "Dream-out", "And Robin shall restore amends.", doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() ); //gNewTotal = gNew - newStart; } { const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n" "<passages count=\"006\" formatversion=\"20020620\">\n" " <wrong error>\n" "</passages>"; XMLDocument doc; doc.Parse( error ); XMLTest( "Bad XML", doc.ErrorID(), XML_ERROR_PARSING_ATTRIBUTE ); } { const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />"; XMLDocument doc; doc.Parse( str ); XMLElement* ele = doc.FirstChildElement(); int iVal, result; double dVal; result = ele->QueryDoubleAttribute( "attr0", &dVal ); XMLTest( "Query attribute: int as double", result, XML_NO_ERROR ); XMLTest( "Query attribute: int as double", (int)dVal, 1 ); result = ele->QueryDoubleAttribute( "attr1", &dVal ); XMLTest( "Query attribute: double as double", (int)dVal, 2 ); result = ele->QueryIntAttribute( "attr1", &iVal ); XMLTest( "Query attribute: double as int", result, XML_NO_ERROR ); XMLTest( "Query attribute: double as int", iVal, 2 ); result = ele->QueryIntAttribute( "attr2", &iVal ); XMLTest( "Query attribute: not a number", result, XML_WRONG_ATTRIBUTE_TYPE ); result = ele->QueryIntAttribute( "bar", &iVal ); XMLTest( "Query attribute: does not exist", result, XML_NO_ATTRIBUTE ); } { const char* str = "<doc/>"; XMLDocument doc; doc.Parse( str ); XMLElement* ele = doc.FirstChildElement(); int iVal; double dVal; ele->SetAttribute( "str", "strValue" ); ele->SetAttribute( "int", 1 ); ele->SetAttribute( "double", -1.0 ); const char* cStr = ele->Attribute( "str" ); ele->QueryIntAttribute( "int", &iVal ); ele->QueryDoubleAttribute( "double", &dVal ); XMLTest( "Attribute match test", ele->Attribute( "str", "strValue" ), "strValue" ); XMLTest( "Attribute round trip. c-string.", "strValue", cStr ); XMLTest( "Attribute round trip. int.", 1, iVal ); XMLTest( "Attribute round trip. double.", -1, (int)dVal ); } { XMLDocument doc; doc.LoadFile( "utf8test.xml" ); // Get the attribute "value" from the "Russian" element and check it. XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" ); const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 }; XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) ); const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U, 0xd1U, 0x81U, 0xd1U, 0x81U, 0xd0U, 0xbaU, 0xd0U, 0xb8U, 0xd0U, 0xb9U, 0 }; const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>"; XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText(); XMLTest( "UTF-8: Browsing russian element name.", russianText, text->Value() ); // Now try for a round trip. doc.SaveFile( "utf8testout.xml" ); // Check the round trip. char savedBuf[256]; char verifyBuf[256]; int okay = 0; #if defined(_MSC_VER) #pragma warning ( push ) #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #endif FILE* saved = fopen( "utf8testout.xml", "r" ); FILE* verify = fopen( "utf8testverify.xml", "r" ); #if defined(_MSC_VER) #pragma warning ( pop ) #endif if ( saved && verify ) { okay = 1; while ( fgets( verifyBuf, 256, verify ) ) { fgets( savedBuf, 256, saved ); NullLineEndings( verifyBuf ); NullLineEndings( savedBuf ); if ( strcmp( verifyBuf, savedBuf ) ) { printf( "verify:%s<\n", verifyBuf ); printf( "saved :%s<\n", savedBuf ); okay = 0; break; } } } if ( saved ) fclose( saved ); if ( verify ) fclose( verify ); XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay ); } // --------GetText()----------- { const char* str = "<foo>This is text</foo>"; XMLDocument doc; doc.Parse( str ); const XMLElement* element = doc.RootElement(); XMLTest( "GetText() normal use.", "This is text", element->GetText() ); str = "<foo><b>This is text</b></foo>"; doc.Parse( str ); element = doc.RootElement(); XMLTest( "GetText() contained element.", element->GetText() == 0, true ); } // ---------- CDATA --------------- { const char* str = "<xmlElement>" "<![CDATA[" "I am > the rules!\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; XMLDocument doc; doc.Parse( str ); doc.Print(); XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), "I am > the rules!\n...since I make symbolic puns", false ); } // ----------- CDATA ------------- { const char* str = "<xmlElement>" "<![CDATA[" "<b>I am > the rules!</b>\n" "...since I make symbolic puns" "]]>" "</xmlElement>"; XMLDocument doc; doc.Parse( str ); doc.Print(); XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(), "<b>I am > the rules!</b>\n...since I make symbolic puns", false ); } // InsertAfterChild causes crash. { // InsertBeforeChild and InsertAfterChild causes crash. XMLDocument doc; XMLElement* parent = doc.NewElement( "Parent" ); doc.InsertFirstChild( parent ); XMLElement* childText0 = doc.NewElement( "childText0" ); XMLElement* childText1 = doc.NewElement( "childText1" ); XMLNode* childNode0 = parent->InsertEndChild( childText0 ); XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 ); XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true ); } { // Entities not being written correctly. // From Lynn Allen const char* passages = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<passages count=\"006\" formatversion=\"20020620\">" "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright ©.\"> </psg>" "</passages>"; XMLDocument doc; doc.Parse( passages ); XMLElement* psg = doc.RootElement()->FirstChildElement(); const char* context = psg->Attribute( "context" ); const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9."; XMLTest( "Entity transformation: read. ", expected, context, true ); #if defined(_MSC_VER) #pragma warning ( push ) #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #endif FILE* textfile = fopen( "textfile.txt", "w" ); #if defined(_MSC_VER) #pragma warning ( pop ) #endif if ( textfile ) { XMLPrinter streamer( textfile ); psg->Accept( &streamer ); fclose( textfile ); } #if defined(_MSC_VER) #pragma warning ( push ) #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #endif textfile = fopen( "textfile.txt", "r" ); #if defined(_MSC_VER) #pragma warning ( pop ) #endif TIXMLASSERT( textfile ); if ( textfile ) { char buf[ 1024 ]; fgets( buf, 1024, textfile ); XMLTest( "Entity transformation: write. ", "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'." " It also has <, >, and &, as well as a fake copyright \xC2\xA9.\"/>\n", buf, false ); } fclose( textfile ); } { // Suppress entities. const char* passages = "<?xml version=\"1.0\" standalone=\"no\" ?>" "<passages count=\"006\" formatversion=\"20020620\">" "<psg context=\"Line 5 has "quotation marks" and 'apostrophe marks'.\">Crazy &ttk;</psg>" "</passages>"; XMLDocument doc( false ); doc.Parse( passages ); XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ), "Line 5 has "quotation marks" and 'apostrophe marks'." ); XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(), "Crazy &ttk;" ); doc.Print(); } { const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>"; XMLDocument doc; doc.Parse( test ); XMLTest( "dot in names", doc.Error(), 0); XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" ); XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" ); } { const char* test = "<element><Name>1.1 Start easy ignore fin thickness
</Name></element>"; XMLDocument doc; doc.Parse( test ); XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText(); XMLTest( "Entity with one digit.", text->Value(), "1.1 Start easy ignore fin thickness\n", false ); } { // DOCTYPE not preserved (950171) // const char* doctype = "<?xml version=\"1.0\" ?>" "<!DOCTYPE PLAY SYSTEM 'play.dtd'>" "<!ELEMENT title (#PCDATA)>" "<!ELEMENT books (title,authors)>" "<element />"; XMLDocument doc; doc.Parse( doctype ); doc.SaveFile( "test7.xml" ); doc.DeleteChild( doc.RootElement() ); doc.LoadFile( "test7.xml" ); doc.Print(); const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown(); XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() ); } { // Comments do not stream out correctly. const char* doctype = "<!-- Somewhat<evil> -->"; XMLDocument doc; doc.Parse( doctype ); XMLComment* comment = doc.FirstChild()->ToComment(); XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() ); } { // Double attributes const char* doctype = "<element attr='red' attr='blue' />"; XMLDocument doc; doc.Parse( doctype ); XMLTest( "Parsing repeated attributes.", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues) doc.PrintError(); } { // Embedded null in stream. const char* doctype = "<element att\0r='red' attr='blue' />"; XMLDocument doc; doc.Parse( doctype ); XMLTest( "Embedded null throws error.", true, doc.Error() ); } { // Empty documents should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717 const char* str = " "; XMLDocument doc; doc.Parse( str ); XMLTest( "Empty document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() ); } { // Low entities XMLDocument doc; doc.Parse( "<test></test>" ); const char result[] = { 0x0e, 0 }; XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result ); doc.Print(); } { // Attribute values with trailing quotes not handled correctly XMLDocument doc; doc.Parse( "<foo attribute=bar\" />" ); XMLTest( "Throw error with bad end quotes.", doc.Error(), true ); } { // [ 1663758 ] Failure to report error on bad XML XMLDocument xml; xml.Parse("<x>"); XMLTest("Missing end tag at end of input", xml.Error(), true); xml.Parse("<x> "); XMLTest("Missing end tag with trailing whitespace", xml.Error(), true); xml.Parse("<x></y>"); XMLTest("Mismatched tags", xml.ErrorID(), XML_ERROR_MISMATCHED_ELEMENT); } { // [ 1475201 ] TinyXML parses entities in comments XMLDocument xml; xml.Parse("<!-- declarations for <head> & <body> -->" "<!-- far & away -->" ); XMLNode* e0 = xml.FirstChild(); XMLNode* e1 = e0->NextSibling(); XMLComment* c0 = e0->ToComment(); XMLComment* c1 = e1->ToComment(); XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true ); XMLTest( "Comments ignore entities.", " far & away ", c1->Value(), true ); } { XMLDocument xml; xml.Parse( "<Parent>" "<child1 att=''/>" "<!-- With this comment, child2 will not be parsed! -->" "<child2 att=''/>" "</Parent>" ); xml.Print(); int count = 0; for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild(); ele; ele = ele->NextSibling() ) { ++count; } XMLTest( "Comments iterate correctly.", 3, count ); } { // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well. unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl"; buf[60] = 239; buf[61] = 0; XMLDocument doc; doc.Parse( (const char*)buf); } { // bug 1827248 Error while parsing a little bit malformed file // Actually not malformed - should work. XMLDocument xml; xml.Parse( "<attributelist> </attributelist >" ); XMLTest( "Handle end tag whitespace", false, xml.Error() ); } { // This one must not result in an infinite loop XMLDocument xml; xml.Parse( "<infinite>loop" ); XMLTest( "Infinite loop test.", true, true ); } #endif { const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>"; XMLDocument doc; doc.Parse( pub ); XMLDocument clone; for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) { XMLNode* copy = node->ShallowClone( &clone ); clone.InsertEndChild( copy ); } clone.Print(); int count=0; const XMLNode* a=clone.FirstChild(); const XMLNode* b=doc.FirstChild(); for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) { ++count; XMLTest( "Clone and Equal", true, a->ShallowEqual( b )); } XMLTest( "Clone and Equal", 4, count ); } // ----------- Performance tracking -------------- { #if defined( _MSC_VER ) __int64 start, end, freq; QueryPerformanceFrequency( (LARGE_INTEGER*) &freq ); #endif #if defined(_MSC_VER) #pragma warning ( push ) #pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. #endif FILE* fp = fopen( "dream.xml", "r" ); #if defined(_MSC_VER) #pragma warning ( pop ) #endif fseek( fp, 0, SEEK_END ); long size = ftell( fp ); fseek( fp, 0, SEEK_SET ); char* mem = new char[size+1]; fread( mem, size, 1, fp ); fclose( fp ); mem[size] = 0; #if defined( _MSC_VER ) QueryPerformanceCounter( (LARGE_INTEGER*) &start ); #else clock_t cstart = clock(); #endif static const int COUNT = 10; for( int i=0; i<COUNT; ++i ) { XMLDocument doc; doc.Parse( mem ); } #if defined( _MSC_VER ) QueryPerformanceCounter( (LARGE_INTEGER*) &end ); #else clock_t cend = clock(); #endif delete [] mem; static const char* note = #ifdef DEBUG "DEBUG"; #else "Release"; #endif #if defined( _MSC_VER ) printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, 1000.0 * (double)(end-start) / ( (double)freq * (double)COUNT) ); #else printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, (double)(cend - cstart)/(double)COUNT ); #endif } #if defined( _MSC_VER ) && defined( DEBUG ) _CrtMemCheckpoint( &endMemState ); //_CrtMemDumpStatistics( &endMemState ); _CrtMemState diffMemState; _CrtMemDifference( &diffMemState, &startMemState, &endMemState ); _CrtMemDumpStatistics( &diffMemState ); //printf( "new total=%d\n", gNewTotal ); #endif printf ("\nPass %d, Fail %d\n", gPass, gFail); return 0; }
int example_1( const char* filename ) { XMLDocument doc; doc.LoadFile( filename ); typedef boost::tokenizer<boost::char_separator<char> > tokenizer; boost::char_separator<char> sep(" \t\n¡!¿?⸘‽“”‘’‛‟.,‚„'\"′″´˝^°¸˛¨`˙˚ªº…:;&_¯–‑—§#⁊¶†‡@%‰‱¦|/\\ˉˆ˘ˇ-‒~*‼⁇⁈⁉$€¢£‹›«»<>{}[]()=+|"); // read in stopwords from text file std::ifstream stopfile("english_stopwords", std::ios_base::in); assert(!stopfile.fail()); std::map<std::string, bool> stopwords_map; // load stopwords into hash map std::string s; stopfile >> s; while (!stopfile.eof()) { stopwords_map[s] = true; stopfile >> s; } stopfile.close(); // assert(!stopfile.fail()); std::map<std::string, int> term_count_map; std::map<std::string, int>::iterator term_count_it; std::map<std::string, std::vector<int> > term_indexVec_map; std::map<std::string, std::vector<int> >::iterator term_indexVec_it; std::map<int, std::string> index_docID_map; std::map<int, std::string> index_term_map; // CONSTANTS int MIN_TERM_LENGTH = 2; int MIN_TERM_COUNT = 2; int docIndex = 0; for (XMLElement* documentElement = doc.FirstChildElement("documents")->FirstChildElement("document"); documentElement; documentElement = documentElement->NextSiblingElement("document")) { // Extract the document ID from the XML XMLElement* docID = documentElement->FirstChildElement("docID"); std::string id_str(docID->GetText()); // Set up hash map of docID string and index keys which will be used in count vectors index_docID_map[docIndex] = id_str; // Extract the document text from the XML XMLElement* docText = documentElement->FirstChildElement("docText"); std::string text_str(docText->GetText()); tokenizer tokens(text_str, sep); for (tokenizer::iterator tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { // std::cout << "<" << *tok_iter << "> "; std::string tmp = *tok_iter; // NOTE: Right now doing a rough length check if (tmp.length() > MIN_TERM_LENGTH) { // Only count terms not in stopwords list if (!stopwords_map.count(tmp)) { // Check for all caps, otherwise convert to lowercase // (maybe should just be turning everything to lowercase...) if (!boost::all(tmp, boost::is_upper())) { boost::to_lower(tmp); } term_count_it = term_count_map.find(tmp); if (term_count_it == term_count_map.end()) { // Initialize term count and doc index vector maps for new term term_count_map[tmp] = 0; std::vector<int> newvec; term_indexVec_map[tmp] = newvec; } term_count_map[tmp]++; term_indexVec_map[tmp].push_back(docIndex); } } } docIndex++; // std::cout << "\n"; } // Now that we have the terms and the documents they came from, we need to // create the actual term-document vectors out of ANN data structures int nPts = 0; // actual number of data points int dim = 0; // dimensionality ANNpointArray dataPts; // data points ANNpoint queryPt; // query point // ANNidxArray nnIdx; // near neighbor indices // ANNdistArray dists; // near neighbor distances ANNkd_tree* kdTree; // search structure nPts = docIndex; // TODO: check for off by one errors!! dim = int(term_count_map.size()); queryPt = annAllocPt(dim); // allocate query point // Allocate the space for points and create array of pointers to coordinate arrays (each dim long) dataPts = annAllocPts(nPts, dim); // allocate data points // Initialize to zero (counts) since ANN code doesn't do this std::fill_n(dataPts[0], nPts*dim, 0); int term_idx = 0; // Run through all of the entries in the term totals and correpsonding doc index vectors for ( term_count_it=term_count_map.begin() ; term_count_it != term_count_map.end(); term_count_it++ ) { // First, check if count passes threshold (could base this on percentiles in future...) if ((*term_count_it).second < MIN_TERM_COUNT) { continue; } // NOTE: Could set up here some sort of entropy thresholds // Record the term with its index as key index_term_map[term_idx] = (*term_count_it).first; // Print std::cout << (*term_count_it).first << " => " << (*term_count_it).second << std::endl; // Convenience vector so iteration and access are more clear std::vector<int> index_vec = term_indexVec_map[(*term_count_it).first]; // Run through doc index vectors and increment counts in real data arrays for ( int ii = 0; ii < index_vec.size(); ii++ ) { std::cout << index_vec[ii] << " "; // Increment count sums dataPts[index_vec[ii]][term_idx] += 1; } std::cout << std::endl; term_idx++; } std::cout << std::endl << term_count_map.size() << " terms in dictionary, " << term_idx << " terms used" << std::endl << std::endl; // DEBUG: Check counts in dataPts arrays // for ( int docIdx = 0; docIdx < nPts; docIdx++ ) // { // for (int termIdx = 0; termIdx < dim; termIdx++) // { // std::cout << dataPts[docIdx][termIdx] << '.'; // } // std::cout << std::endl; // } // Build the ANN kd-tree data structure for fast NN lookups kdTree = new ANNkd_tree( // build search structure dataPts, // the data points nPts, // number of points dim); // dimension of space // kdTree->annkSearch( // search // queryPt, // query point // k, // number of near neighbors // nnIdx, // nearest neighbors (returned) // dists, // distance (returned) // eps); // error bound // int annkFRSearch( // approx fixed-radius kNN search // ANNpoint q, // the query point // ANNdist sqRad, // squared radius of query ball // int k, // number of neighbors to return // ANNidxArray nn_idx = NULL, // nearest neighbor array (modified) // ANNdistArray dd = NULL, // dist to near neighbors (modified) // double eps=0.0); // error bound return doc.ErrorID(); }
void Game::LoadMap( const std::string & filename ) { XMLDocument doc; doc.LoadFile(filename.c_str()); if ( doc.ErrorID() != XML_NO_ERROR ) { ostringstream ss; ss << "Loadfile:" << g_TinyXmlErrors[doc.ErrorID()] << " " << doc.GetErrorStr1() << " " << doc.GetErrorStr2(); throw XmlParsingException(ss.str()); } // Load rooms XMLElement *pElem = doc.FirstChildElement( "Room"); while( pElem != NULL ) { g_Log << "loading..." << pElem->Attribute("id"); Room *pRoom = NULL; // Custom rooms if ( pElem->Attribute("class")) { std::string classID = pElem->Attribute("class"); pRoom = RoomFactory::Create(classID); } else { pRoom = new Room(); } pRoom->Load( *pElem ); if ( m_Rooms.find(pRoom->GetId()) != m_Rooms.end()) { throw DuplicateRoomIdException(pRoom->GetId()); } m_Rooms[pRoom->GetId()] = pRoom; pElem = pElem->NextSiblingElement("Room"); } // Load transitions pElem = doc.FirstChildElement( "Transitions"); if ( pElem != NULL ) { pElem = pElem->FirstChildElement("Transition"); while( pElem != NULL ) { const char * from = pElem->Attribute("from"); const char * to = pElem->Attribute("to"); const char * direction = pElem->Attribute("direction"); const char * oneway = pElem->Attribute("oneway"); if ( direction == NULL ) throw AttributeMissingException("Direction is missing from transition"); if ( from == NULL ) throw AttributeMissingException("From attribute is missing from transition!"); if ( to == NULL ) throw AttributeMissingException("To attribute is missing from transition!"); // check is from a proper id if ( m_Rooms.find(from) == m_Rooms.end() ) { ostringstream ss; ss << from << " is not a proper room id"; throw InvalidAttributeException(ss.str()); } // check is to a proper id if ( m_Rooms.find(to) == m_Rooms.end() ) { ostringstream ss; ss << to << " is not a proper room id"; throw InvalidAttributeException(ss.str()); } string tmp = direction; transform(tmp.begin(),tmp.end(), tmp.begin(), [] (char c){ return tolower(c);}); Direction dir = kNumDirs; if ( tmp == "east" ) dir = East; else if ( tmp == "north" ) dir = North; else if ( tmp == "south" ) dir = South; else if ( tmp == "west" ) dir = West; else throw InvalidAttributeException("Direction is not properly set"); m_Rooms[from]->SetNextRoom(dir, m_Rooms[to]); if ( !oneway ) { m_Rooms[to]->SetNextRoom(g_Opposite[dir], m_Rooms[from]); } pElem = pElem->NextSiblingElement("Transition"); } } else { throw ElementMissingException("Transitions is missing!"); } // set current room pElem = doc.FirstChildElement("OnStart"); if ( pElem == NULL ) throw ElementMissingException("No OnStart defined"); pElem = pElem->FirstChildElement("CurrentRoom"); if ( pElem == NULL ) { cout << "No current room set, problems might arise\n"; } else { const char *szRoomId = pElem->Attribute("id"); if ( szRoomId == NULL) throw InvalidAttributeException("Bad format CurrentRoom"); string tmp = szRoomId; if ( m_Rooms.find(tmp) == m_Rooms.end() ) { ostringstream ss; ss << "No room " << tmp << " found!"; throw ElementMissingException(ss.str()); } SetCurrentRoom(m_Rooms[tmp]); } pElem = doc.FirstChildElement("OnStart"); pElem = pElem->FirstChildElement("Story"); if ( pElem == NULL ) throw ElementMissingException("Story"); m_Story = (pElem->GetText() == NULL) ? "" : pElem->GetText(); pElem = doc.FirstChildElement("Player"); if ( !pElem ) throw new ElementMissingException("Player"); m_Player.Load(*pElem); }
void XmlReader::xmlReadAll(void) { XMLDocument doc; doc.LoadFile(m_filename); if (doc.ErrorID() != 0) { printf("read xml error!\n"); return; } XMLElement *root = doc.FirstChildElement("root"); XMLElement *dev_id = root->FirstChildElement("dev_id"); XMLElement *user_account = root->FirstChildElement("user_acount"); XMLElement *vsp_url = root->FirstChildElement("vsp_url"); XMLElement *code = root->FirstChildElement("code"); XMLElement *msg = root->FirstChildElement("msg"); printf("dev_id: %s\n", dev_id->GetText()); printf("user_account: %s\n", user_account->GetText()); printf("vsp_url: %s\n", vsp_url->GetText());; printf("code: %s\n", code->GetText()); printf("msg: %s\n", msg->GetText()); printf("============================================\n"); XMLElement *user = root->FirstChildElement("user"); XMLElement *user_id = user->FirstChildElement("user_id"); XMLElement *user1_account = user->FirstChildElement("user_acount"); XMLElement *user_name = user->FirstChildElement("user_name"); XMLElement *big_visit_num = user->FirstChildElement("big_visit_num"); XMLElement *vsp_id = user->FirstChildElement("vsp_id"); XMLElement *vsp_name = user->FirstChildElement("vsp_name"); printf("user_id: %s\n", user_id->GetText()); printf("user1_account: %s\n", user1_account->GetText()); printf("user_name: %s\n", user_name->GetText()); printf("big_visit_num: %s\n", big_visit_num->GetText()); printf("vsp_id: %s\n", vsp_id->GetText()); printf("vsp_name: %s\n", vsp_name->GetText()); printf("================================================\n"); XMLElement *contacts = root->FirstChildElement("contacts"); for (XMLElement *contact = contacts->FirstChildElement("contact"); contact; contact = contact->NextSiblingElement("contact")) { XMLElement *user2_id = contact->FirstChildElement("user_id"); XMLElement *user2_account = contact->FirstChildElement("user_acount"); XMLElement *user2_name = contact->FirstChildElement("user_name"); printf("user_id: %s\n", user2_id->GetText()); printf("user_account: %s\n", user2_account->GetText()); printf("user_name: %s\n", user2_name->GetText()); printf("\n"); } printf("================================================\n"); XMLElement *meetings = root->FirstChildElement("meetings"); for (XMLElement *meeting = meetings->FirstChildElement("meeting"); meeting; meeting = meeting->NextSiblingElement("meeting")) { XMLElement *meeting_id = meeting->FirstChildElement("meeting_id"); XMLElement *meeting_name = meeting->FirstChildElement("meeting_name"); XMLElement *start_time = meeting->FirstChildElement("start_time"); XMLElement *end_time = meeting->FirstChildElement("end_time"); XMLElement *meeting_conferrees = meeting->FirstChildElement("meeting_conferrees"); printf("meeting_id: %s\n", meeting_id->GetText()); printf("meeting_name: %s\n", meeting_name->GetText()); printf("start_time: %s\n", start_time->GetText()); printf("end_time: %s\n", end_time->GetText()); printf("conferreess:\n"); if (meeting_conferrees) { for (XMLElement *meeting_conferree = meeting_conferrees->FirstChildElement("meeting_conferree"); meeting_conferree; meeting_conferree = meeting_conferree->NextSiblingElement("meeting_conferree")) { XMLElement *user2_id = meeting_conferree->FirstChildElement("user_id"); XMLElement *user2_account = meeting_conferree->FirstChildElement("user_acount"); XMLElement *user2_name = meeting_conferree->FirstChildElement("user_name"); printf("user_id: %s\n", user2_id->GetText()); printf("user_account: %s\n", user2_account->GetText()); printf("user_name: %s\n", user2_name->GetText()); } } printf("\n"); } printf("==========================================================\n"); XMLElement *msms = root->FirstChildElement("msms"); for (XMLElement *msm = msms->FirstChildElement("msm"); msm; msm = msm->NextSiblingElement("msm")) { XMLElement *msm_ip = msm->FirstChildElement("msm_ip"); XMLElement *msm_port = msm->FirstChildElement("msm_port"); printf("msm_ip: %s\n", msm_ip->GetText()); printf("msm_port: %s\n", msm_port->GetText()); } }
const Material MaterialLoader::loadFromXML(const std::string &path) { std::string dir = path.substr(0, path.find_last_of("/\\")); XMLDocument doc; XMLError error = doc.LoadFile((Environment::getDataDir() + "/textures/" + path + ".gmd").c_str()); if (error != XML_NO_ERROR) { System::Log(Error, "MaterialLoader") << "XML Error " << doc.ErrorID() << ": " << doc.ErrorName() << " in " << path; } XMLHandle docHandle(&doc); XMLElement *root = docHandle.FirstChildElement().ToElement(); XMLHandle rootH(root); std::string name = root->Attribute("name"); std::string fancyname = root->Attribute("fancyname"); Material mat; mat.name = name; mat.fancyname = fancyname; XMLElement *diffE = rootH.FirstChildElement("diffuse").ToElement(); if (diffE) { std::string diffP = diffE->Attribute("path"); if (diffP.length() > 0) { diffP = dir + "/" + diffP; System::Log(Debug, "MaterialLoader") << mat.name << ": load " << diffP; mat.diffuse = TextureLoader::getTexture(diffP); } } else { mat.diffuse = TextureLoader::getEmptyDiffuse(); } XMLElement *normE = rootH.FirstChildElement("normal").ToElement(); if (normE) { std::string normP = normE->Attribute("path"); if (normP.length() > 0) { normP = dir + "/" + normP; System::Log(Debug, "MaterialLoader") << mat.name << ": load " << normP; mat.normal = TextureLoader::getTexture(normP); } } else { mat.normal = TextureLoader::getEmptyNormal(); } XMLElement *specE = rootH.FirstChildElement("specular").ToElement(); if (specE) { std::string specP = specE->Attribute("path"); if (specP.length() > 0) { specP = dir + "/" + specP; System::Log(Debug, "MaterialLoader") << mat.name << ": load " << specP; mat.specular = TextureLoader::getTexture(specP); } specE->QueryFloatAttribute("shininess", &mat.shininess); } else { mat.specular = TextureLoader::getEmptySpecular(); } XMLElement *surfaceE = rootH.FirstChildElement("surface").ToElement(); mat.portalable = false; if (surfaceE) { surfaceE->QueryBoolAttribute("portalable", &mat.portalable); } XMLElement *scaleE = rootH.FirstChildElement("scale").ToElement(); if (scaleE) { scaleE->QueryFloatAttribute("u", &mat.scaleU); scaleE->QueryFloatAttribute("v", &mat.scaleV); } XMLElement *kindE = rootH.FirstChildElement("kind").ToElement(); if (kindE) { mat.kind = std::string(kindE->GetText()); } XMLElement *tagsE = rootH.FirstChildElement("tags").ToElement(); if (tagsE) { std::string tagStr(tagsE->GetText()); size_t start = 0; size_t index = tagStr.find(",", start); while (index != std::string::npos) { mat.tags.push_back(tagStr.substr(start, index - start)); start = index + 1; index = tagStr.find(",", start); } if (start != std::string::npos) { mat.tags.push_back(tagStr.substr(start)); } } // TODO return mat; }
// Loads a level file int _Level::Init(const std::string &LevelName, bool HeaderOnly) { if(!HeaderOnly) Log.Write("_Level::Init - Loading level: %s", LevelName.c_str()); // Get paths this->LevelName = LevelName; LevelNiceName = ""; std::string LevelFile = LevelName + "/" + LevelName + ".xml"; std::string FilePath = Game.GetWorkingPath() + std::string("levels/") + LevelFile; std::string CustomFilePath = Save.GetCustomLevelsPath() + LevelFile; std::string DataPath = Game.GetWorkingPath() + std::string("levels/") + LevelName + "/"; // See if custom level exists first IsCustomLevel = false; std::ifstream CustomLevelExists(CustomFilePath.c_str()); if(CustomLevelExists) { IsCustomLevel = true; FilePath = CustomFilePath; DataPath = Save.GetCustomLevelsPath() + LevelName + "/"; } CustomLevelExists.close(); // Open the XML file XMLDocument Document; if(Document.LoadFile(FilePath.c_str()) != XML_NO_ERROR) { Log.Write("Error loading level file with error id = %d", Document.ErrorID()); Log.Write("Error string 1: %s", Document.GetErrorStr1()); Log.Write("Error string 2: %s", Document.GetErrorStr2()); Close(); return 0; } // Check for level tag XMLElement *LevelElement = Document.FirstChildElement("level"); if(!LevelElement) { Log.Write("Could not find level tag"); Close(); return 0; } // Level version if(LevelElement->QueryIntAttribute("version", &LevelVersion) == XML_NO_ATTRIBUTE) { Log.Write("Could not find level version"); Close(); return 0; } // Check required game version GameVersion = LevelElement->Attribute("gameversion"); if(GameVersion == "") { Log.Write("Could not find game version attribute"); Close(); return 0; } // Load level info XMLElement *InfoElement = LevelElement->FirstChildElement("info"); if(InfoElement) { XMLElement *NiceNameElement = InfoElement->FirstChildElement("name"); if(NiceNameElement) { LevelNiceName = NiceNameElement->GetText(); } } // Return after header is read if(HeaderOnly) { Close(); return true; } // Load default lua script Scripts.clear(); Scripts.push_back(Game.GetWorkingPath() + "scripts/default.lua"); // Options bool Fog = false; bool EmitLight = false; Level.ClearColor.set(255, 0, 0, 0); // Load options XMLElement *OptionsElement = LevelElement->FirstChildElement("options"); if(OptionsElement) { // Does the player emit light? XMLElement *EmitLightElement = OptionsElement->FirstChildElement("emitlight"); if(EmitLightElement) { EmitLightElement->QueryBoolAttribute("enabled", &EmitLight); } } // Load world XMLElement *ResourcesElement = LevelElement->FirstChildElement("resources"); if(ResourcesElement) { // Load scenes for(XMLElement *SceneElement = ResourcesElement->FirstChildElement("scene"); SceneElement != 0; SceneElement = SceneElement->NextSiblingElement("scene")) { // Get file std::string File = SceneElement->Attribute("file"); if(File == "") { Log.Write("Could not find file attribute on scene"); Close(); return 0; } // Reset fog irrDriver->setFog(video::SColor(0, 0, 0, 0), video::EFT_FOG_EXP, 0, 0, 0.0f); // Load scene if(IsCustomLevel) { irrFile->changeWorkingDirectoryTo(DataPath.c_str()); irrScene->loadScene(File.c_str(), &UserDataLoader); irrFile->changeWorkingDirectoryTo(Game.GetWorkingPath().c_str()); } else { irrScene->loadScene((DataPath + File).c_str(), &UserDataLoader); } // Set texture filters on meshes in the scene core::array<irr::scene::ISceneNode *> MeshNodes; irrScene->getSceneNodesFromType(scene::ESNT_MESH, MeshNodes); for(u32 i = 0; i < MeshNodes.size(); i++) { if(EmitLight && Config.Shaders) { video::SMaterial &Material = MeshNodes[i]->getMaterial(0); int ShaderType = 0; if(Material.MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL) { ShaderType = 1; } MeshNodes[i]->setMaterialType((video::E_MATERIAL_TYPE)Graphics.GetCustomMaterial(ShaderType)); } MeshNodes[i]->setMaterialFlag(video::EMF_TRILINEAR_FILTER, Config.TrilinearFiltering); for(u32 j = 0; j < MeshNodes[i]->getMaterialCount(); j++) { for(int k = 0; k < 4; k++) { MeshNodes[i]->getMaterial(j).TextureLayer[k].AnisotropicFilter = Config.AnisotropicFiltering; if(MeshNodes[i]->getMaterial(j).FogEnable) Fog = true; } } } } // Load collision for(XMLElement *CollisionElement = ResourcesElement->FirstChildElement("collision"); CollisionElement != 0; CollisionElement = CollisionElement->NextSiblingElement("collision")) { // Get file std::string File = CollisionElement->Attribute("file"); if(File == "") { Log.Write("Could not find file attribute on collision"); Close(); return 0; } // Create template TemplateStruct *Template = new TemplateStruct; Template->CollisionFile = DataPath + File; Template->Type = _Object::COLLISION; Template->Mass = 0.0f; Templates.push_back(Template); // Create spawn SpawnStruct *ObjectSpawn = new SpawnStruct; ObjectSpawn->Template = Template; ObjectSpawns.push_back(ObjectSpawn); } // Load scripts for(XMLElement *ScriptElement = ResourcesElement->FirstChildElement("script"); ScriptElement != 0; ScriptElement = ScriptElement->NextSiblingElement("script")) { // Get file std::string File = ScriptElement->Attribute("file"); if(File == "") { Log.Write("Could not find file attribute on script"); Close(); return 0; } Scripts.push_back(DataPath + File); } // Load sounds Sounds.clear(); for(XMLElement *SoundElement = ResourcesElement->FirstChildElement("sound"); SoundElement != 0; SoundElement = SoundElement->NextSiblingElement("sound")) { // Get file std::string File = SoundElement->Attribute("file"); if(File == "") { Log.Write("Could not find file attribute on sound"); Close(); return 0; } // Attempt to load sound if(Audio.LoadBuffer(File)) Sounds.push_back(File); } } // Load templates XMLElement *TemplatesElement = LevelElement->FirstChildElement("templates"); if(TemplatesElement) { int TemplateID = 0; for(XMLElement *TemplateElement = TemplatesElement->FirstChildElement(); TemplateElement != 0; TemplateElement = TemplateElement->NextSiblingElement()) { // Create a template TemplateStruct *Template = new TemplateStruct; Template->Fog = Fog; // Get the template properties if(!GetTemplateProperties(TemplateElement, *Template)) return 0; // Assign options Template->TemplateID = TemplateID; if(EmitLight) { // Use shaders on materials that receive light if(Config.Shaders) Template->CustomMaterial = Graphics.GetCustomMaterial(0); // Set the player to emit light if(Template->Type == _Object::PLAYER || Template->Type == _Object::ORB) Template->EmitLight = true; } TemplateID++; // Store for later Templates.push_back(Template); } } // Load object spawns XMLElement *ObjectsElement = LevelElement->FirstChildElement("objects"); if(ObjectsElement) { for(XMLElement *ObjectElement = ObjectsElement->FirstChildElement(); ObjectElement != 0; ObjectElement = ObjectElement->NextSiblingElement()) { // Create an object spawn SpawnStruct *ObjectSpawn = new SpawnStruct; // Get the object properties if(!GetObjectSpawnProperties(ObjectElement, *ObjectSpawn)) return 0; // Store for later ObjectSpawns.push_back(ObjectSpawn); } } return 1; }