Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages | Examples

xmltest.cpp

Go to the documentation of this file.
00001 /*
00002    Test program for TinyXML.
00003 */
00004 
00005 
00006 #include <tinyxml.h>
00007 
00008 #ifdef TIXML_USE_STL
00009         #include <iostream>
00010         #include <sstream>
00011         using namespace std;
00012 #else
00013         #include <stdio.h>
00014 #endif
00015 
00016 #if defined( WIN32 ) && defined( TUNE )
00017         #include <crtdbg.h>
00018         _CrtMemState startMemState;
00019         _CrtMemState endMemState;
00020 #endif
00021 
00022 static int gPass = 0;
00023 static int gFail = 0;
00024 
00025 
00026 bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false)
00027 {
00028         bool pass = !strcmp( expected, found );
00029         if ( pass )
00030                 printf ("[pass]");
00031         else
00032                 printf ("[fail]");
00033 
00034         if ( noEcho )
00035                 printf (" %s\n", testString);
00036         else
00037                 printf (" %s [%s][%s]\n", testString, expected, found);
00038 
00039         if ( pass )
00040                 ++gPass;
00041         else
00042                 ++gFail;
00043         return pass;
00044 }
00045 
00046 
00047 bool XmlTest( const char* testString, int expected, int found, bool noEcho = false )
00048 {
00049         bool pass = ( expected == found );
00050         if ( pass )
00051                 printf ("[pass]");
00052         else
00053                 printf ("[fail]");
00054 
00055         if ( noEcho )
00056                 printf (" %s\n", testString);
00057         else
00058                 printf (" %s [%d][%d]\n", testString, expected, found);
00059 
00060         if ( pass )
00061                 ++gPass;
00062         else
00063                 ++gFail;
00064         return pass;
00065 }
00066 
00067 
00068 //
00069 // This file demonstrates some basic functionality of TinyXml.
00070 // Note that the example is very contrived. It presumes you know
00071 // what is in the XML file. But it does test the basic operations,
00072 // and show how to add and remove nodes.
00073 //
00074 
00075 int main()
00076 {
00077         //
00078         // We start with the 'demoStart' todo list. Process it. And
00079         // should hopefully end up with the todo list as illustrated.
00080         //
00081         const char* demoStart =
00082                 "<?xml version=\"1.0\"  standalone='no' >\n"
00083                 "<!-- Our to do list data -->"
00084                 "<ToDo>\n"
00085                 "<!-- Do I need a secure PDA? -->\n"
00086                 "<Item priority=\"1\" distance='close'> Go to the <bold>Toy store!</bold></Item>"
00087                 "<Item priority=\"2\" distance='none'> Do bills   </Item>"
00088                 "<Item priority=\"2\" distance='far &amp; back'> Look for Evil Dinosaurs! </Item>"
00089                 "</ToDo>";
00090 
00091 #ifdef TIXML_USE_STL
00092         /*      What the todo list should look like after processing.
00093                 In stream (no formatting) representation. */
00094         const char* demoEnd =
00095                 "<?xml version=\"1.0\" standalone=\"no\" ?>"
00096                 "<!-- Our to do list data -->"
00097                 "<ToDo>"
00098                 "<!-- Do I need a secure PDA? -->"
00099                 "<Item priority=\"2\" distance=\"close\">Go to the"
00100                 "<bold>Toy store!"
00101                 "</bold>"
00102                 "</Item>"
00103                 "<Item priority=\"1\" distance=\"far\">Talk to:"
00104                 "<Meeting where=\"School\">"
00105                 "<Attendee name=\"Marple\" position=\"teacher\" />"
00106                 "<Attendee name=\"Voel\" position=\"counselor\" />"
00107                 "</Meeting>"
00108                 "<Meeting where=\"Lunch\" />"
00109                 "</Item>"
00110                 "<Item priority=\"2\" distance=\"here\">Do bills"
00111                 "</Item>"
00112                 "</ToDo>";
00113 #endif
00114 
00115         // The example parses from the character string (above):
00116         #if defined( WIN32 ) && defined( TUNE )
00117         _CrtMemCheckpoint( &startMemState );
00118         #endif  
00119 
00120         {
00121                 // Write to a file and read it back, to check file I/O.
00122 
00123                 TiXmlDocument doc( "demotest.xml" );
00124                 doc.Parse( demoStart );
00125 
00126                 if ( doc.Error() )
00127                 {
00128                         printf( "Error in %s: %s\n", doc.Value(), doc.ErrorDesc() );
00129                         exit( 1 );
00130                 }
00131                 doc.SaveFile();
00132         }
00133 
00134         TiXmlDocument doc( "demotest.xml" );
00135         bool loadOkay = doc.LoadFile();
00136 
00137         if ( !loadOkay )
00138         {
00139                 printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.\n", doc.ErrorDesc() );
00140                 exit( 1 );
00141         }
00142 
00143         printf( "** Demo doc read from disk: ** \n\n" );
00144         doc.Print( stdout );
00145 
00146         TiXmlNode* node = 0;
00147         TiXmlElement* todoElement = 0;
00148         TiXmlElement* itemElement = 0;
00149 
00150 
00151         // --------------------------------------------------------
00152         // An example of changing existing attributes, and removing
00153         // an element from the document.
00154         // --------------------------------------------------------
00155 
00156         // Get the "ToDo" element.
00157         // It is a child of the document, and can be selected by name.
00158         node = doc.FirstChild( "ToDo" );
00159         assert( node );
00160         todoElement = node->ToElement();
00161         assert( todoElement  );
00162 
00163         // Going to the toy store is now our second priority...
00164         // So set the "priority" attribute of the first item in the list.
00165         node = todoElement->FirstChildElement();        // This skips the "PDA" comment.
00166         assert( node );
00167         itemElement = node->ToElement();
00168         assert( itemElement  );
00169         itemElement->SetAttribute( "priority", 2 );
00170 
00171         // Change the distance to "doing bills" from
00172         // "none" to "here". It's the next sibling element.
00173         itemElement = itemElement->NextSiblingElement();
00174         assert( itemElement );
00175         itemElement->SetAttribute( "distance", "here" );
00176 
00177         // Remove the "Look for Evil Dinosaurs!" item.
00178         // It is 1 more sibling away. We ask the parent to remove
00179         // a particular child.
00180         itemElement = itemElement->NextSiblingElement();
00181         todoElement->RemoveChild( itemElement );
00182 
00183         itemElement = 0;
00184 
00185         // --------------------------------------------------------
00186         // What follows is an example of created elements and text
00187         // nodes and adding them to the document.
00188         // --------------------------------------------------------
00189 
00190         // Add some meetings.
00191         TiXmlElement item( "Item" );
00192         item.SetAttribute( "priority", "1" );
00193         item.SetAttribute( "distance", "far" );
00194 
00195         TiXmlText text( "Talk to:" );
00196 
00197         TiXmlElement meeting1( "Meeting" );
00198         meeting1.SetAttribute( "where", "School" );
00199 
00200         TiXmlElement meeting2( "Meeting" );
00201         meeting2.SetAttribute( "where", "Lunch" );
00202 
00203         TiXmlElement attendee1( "Attendee" );
00204         attendee1.SetAttribute( "name", "Marple" );
00205         attendee1.SetAttribute( "position", "teacher" );
00206 
00207         TiXmlElement attendee2( "Attendee" );
00208         attendee2.SetAttribute( "name", "Voel" );
00209         attendee2.SetAttribute( "position", "counselor" );
00210 
00211         // Assemble the nodes we've created:
00212         meeting1.InsertEndChild( attendee1 );
00213         meeting1.InsertEndChild( attendee2 );
00214 
00215         item.InsertEndChild( text );
00216         item.InsertEndChild( meeting1 );
00217         item.InsertEndChild( meeting2 );
00218 
00219         // And add the node to the existing list after the first child.
00220         node = todoElement->FirstChild( "Item" );
00221         assert( node );
00222         itemElement = node->ToElement();
00223         assert( itemElement );
00224 
00225         todoElement->InsertAfterChild( itemElement, item );
00226 
00227         printf( "\n** Demo doc processed: ** \n\n" );
00228         doc.Print( stdout );
00229 
00230 
00231 #ifdef TIXML_USE_STL
00232         printf( "** Demo doc processed to stream: ** \n\n" );
00233         cout << doc << endl << endl;
00234 #endif
00235 
00236         // --------------------------------------------------------
00237         // Different tests...do we have what we expect?
00238         // --------------------------------------------------------
00239 
00240         int count = 0;
00241         TiXmlElement*   element;
00242 
00243         //////////////////////////////////////////////////////
00244 
00245 #ifdef TIXML_USE_STL
00246         cout << "** Basic structure. **\n";
00247         ostringstream outputStream( ostringstream::out );
00248         outputStream << doc;
00249         XmlTest( "Output stream correct.",      string( demoEnd ).c_str(),
00250                                                                                 outputStream.str().c_str(), true );
00251 #endif
00252 
00253         node = doc.RootElement();
00254         XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
00255         XmlTest ( "Root element value is 'ToDo'.", "ToDo",  node->Value());
00256 
00257         node = node->FirstChild();
00258         XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
00259         node = node->NextSibling();
00260         XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
00261         XmlTest ( "Value is 'Item'.", "Item", node->Value() );
00262 
00263         node = node->FirstChild();
00264         XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
00265         XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );
00266 
00267 
00268         //////////////////////////////////////////////////////
00269         printf ("\n** Iterators. **\n");
00270 
00271         // Walk all the top level nodes of the document.
00272         count = 0;
00273         for( node = doc.FirstChild();
00274                  node;
00275                  node = node->NextSibling() )
00276         {
00277                 count++;
00278         }
00279         XmlTest( "Top level nodes, using First / Next.", 3, count );
00280 
00281         count = 0;
00282         for( node = doc.LastChild();
00283                  node;
00284                  node = node->PreviousSibling() )
00285         {
00286                 count++;
00287         }
00288         XmlTest( "Top level nodes, using Last / Previous.", 3, count );
00289 
00290         // Walk all the top level nodes of the document,
00291         // using a different syntax.
00292         count = 0;
00293         for( node = doc.IterateChildren( 0 );
00294                  node;
00295                  node = doc.IterateChildren( node ) )
00296         {
00297                 count++;
00298         }
00299         XmlTest( "Top level nodes, using IterateChildren.", 3, count );
00300 
00301         // Walk all the elements in a node.
00302         count = 0;
00303         for( element = todoElement->FirstChildElement();
00304                  element;
00305                  element = element->NextSiblingElement() )
00306         {
00307                 count++;
00308         }
00309         XmlTest( "Children of the 'ToDo' element, using First / Next.",
00310                 3, count );
00311 
00312         // Walk all the elements in a node by value.
00313         count = 0;
00314         for( node = todoElement->FirstChild( "Item" );
00315                  node;
00316                  node = node->NextSibling( "Item" ) )
00317         {
00318                 count++;
00319         }
00320         XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );
00321 
00322         count = 0;
00323         for( node = todoElement->LastChild( "Item" );
00324                  node;
00325                  node = node->PreviousSibling( "Item" ) )
00326         {
00327                 count++;
00328         }
00329         XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );
00330 
00331 #ifdef TIXML_USE_STL
00332         {
00333                 cout << "\n** Parsing. **\n";
00334                 istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '&gt;' />" );
00335                 TiXmlElement element0( "default" );
00336                 parse0 >> element0;
00337 
00338                 XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
00339                 XmlTest ( "Reads attribute 'attribute0=\"foo0\"'.", "foo0", element0.Attribute( "attribute0" ));
00340                 XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
00341                 XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
00342         }
00343 #endif
00344 
00345         {
00346                 const char* error =     "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
00347                                                         "<passages count=\"006\" formatversion=\"20020620\">\n"
00348                                                         "    <wrong error>\n"
00349                                                         "</passages>";
00350 
00351         TiXmlDocument doc;
00352                 doc.Parse( error );
00353                 XmlTest( "Error row", doc.ErrorRow(), 3 );
00354                 XmlTest( "Error column", doc.ErrorCol(), 17 );
00355                 //printf( "error=%d id='%s' row %d col%d\n", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );
00356 
00357         }
00358         {
00359                 const char* str =       "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
00360                                                         "  <!-- Silly example -->\n"
00361                                                         "    <door wall='north'>A great door!</door>\n"
00362                                                         "\t<door wall='east'/>"
00363                                                         "</room>";
00364 
00365         TiXmlDocument doc;
00366                 doc.Parse( str );
00367 
00368                 TiXmlHandle docHandle( &doc );
00369                 TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
00370                 TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
00371                 TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
00372                 TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
00373                 TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );
00374 
00375                 assert( docHandle.Node() );
00376                 assert( roomHandle.Element() );
00377                 assert( commentHandle.Node() );
00378                 assert( textHandle.Text() );
00379                 assert( door0Handle.Element() );
00380                 assert( door1Handle.Element() );
00381 
00382                 TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
00383                 assert( declaration );
00384                 TiXmlElement* room = roomHandle.Element();
00385                 assert( room );
00386                 TiXmlAttribute* doors = room->FirstAttribute();
00387                 assert( doors );
00388                 TiXmlText* text = textHandle.Text();
00389                 TiXmlComment* comment = commentHandle.Node()->ToComment();
00390                 assert( comment );
00391                 TiXmlElement* door0 = door0Handle.Element();
00392                 TiXmlElement* door1 = door1Handle.Element();
00393 
00394                 XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
00395                 XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
00396                 XmlTest( "Location tracking: room row", room->Row(), 1 );
00397                 XmlTest( "Location tracking: room col", room->Column(), 45 );
00398                 XmlTest( "Location tracking: doors row", doors->Row(), 1 );
00399                 XmlTest( "Location tracking: doors col", doors->Column(), 51 );
00400                 XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
00401                 XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
00402                 XmlTest( "Location tracking: text row", text->Row(), 3 ); 
00403                 XmlTest( "Location tracking: text col", text->Column(), 24 );
00404                 XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
00405                 XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
00406                 XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
00407                 XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
00408         }
00409         {
00410                 const char* str =       "\t<?xml version=\"1.0\" standalone=\"no\" ?>\t<room doors='2'>\n"
00411                                                         "</room>";
00412 
00413         TiXmlDocument doc;
00414                 doc.SetTabSize( 8 );
00415                 doc.Parse( str );
00416 
00417                 TiXmlHandle docHandle( &doc );
00418                 TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
00419 
00420                 assert( docHandle.Node() );
00421                 assert( roomHandle.Element() );
00422 
00423                 TiXmlElement* room = roomHandle.Element();
00424                 assert( room );
00425                 TiXmlAttribute* doors = room->FirstAttribute();
00426                 assert( doors );
00427 
00428                 XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
00429                 XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
00430                 XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
00431                 XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
00432         }
00433 
00434         {
00435                 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
00436 
00437                 TiXmlDocument doc;
00438                 doc.Parse( str );
00439 
00440                 TiXmlElement* ele = doc.FirstChildElement();
00441 
00442                 int iVal, result;
00443                 double dVal;
00444 
00445                 result = ele->QueryDoubleAttribute( "attr0", &dVal );
00446                 XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
00447                 XmlTest( "Query attribute: int as double", (int)dVal, 1 );
00448                 result = ele->QueryDoubleAttribute( "attr1", &dVal );
00449                 XmlTest( "Query attribute: double as double", (int)dVal, 2 );
00450                 result = ele->QueryIntAttribute( "attr1", &iVal );
00451                 XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
00452                 XmlTest( "Query attribute: double as int", iVal, 2 );
00453                 result = ele->QueryIntAttribute( "attr2", &iVal );
00454                 XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
00455                 result = ele->QueryIntAttribute( "bar", &iVal );
00456                 XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
00457         }
00458 
00459 #ifdef TIXML_USE_STL
00460         {
00461                 //////////////////////////////////////////////////////
00462                 cout << "\n** Streaming. **\n";
00463 
00464                 // Round trip check: stream in, then stream back out to verify. The stream
00465                 // out has already been checked, above. We use the output
00466 
00467                 istringstream inputStringStream( outputStream.str() );
00468                 TiXmlDocument document0;
00469 
00470                 inputStringStream >> document0;
00471 
00472                 ostringstream outputStream0( ostringstream::out );
00473                 outputStream0 << document0;
00474 
00475                 XmlTest( "Stream round trip correct.",  string( demoEnd ).c_str(), 
00476                                                                                                 outputStream0.str().c_str(), true );
00477 
00478                 std::string str;
00479                 str << document0;
00480 
00481                 XmlTest( "String printing correct.", string( demoEnd ).c_str(), 
00482                                                                                          str.c_str(), true );
00483         }
00484 #endif
00485 
00486         // --------------------------------------------------------
00487         // UTF-8 testing. It is important to test:
00488         //      1. Making sure name, value, and text read correctly
00489         //      2. Row, Col functionality
00490         //      3. Correct output
00491         // --------------------------------------------------------
00492         printf ("\n** UTF-8 **\n");
00493         {
00494                 TiXmlDocument doc( "utf8test.xml" );
00495                 doc.LoadFile();
00496                 if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) {
00497                         printf( "WARNING: File 'utf8test.xml' not found.\n"
00498                                         "(Are you running the test from the wrong directory?)\n"
00499                                     "Could not test UTF-8 functionality.\n" );
00500                 }
00501                 else
00502                 {
00503                         TiXmlHandle docH( &doc );
00504                         // Get the attribute "value" from the "Russian" element and check it.
00505                         TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
00506                         const unsigned char correctValue[] = {  0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, 
00507                                                                                                         0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
00508 
00509                         XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
00510                         XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
00511                         XmlTest( "UTF-8: Russian value column.", 5, element->Column() );
00512 
00513                         const unsigned char russianElementName[] = {    0xd0U, 0xa0U, 0xd1U, 0x83U,
00514                                                                                                                         0xd1U, 0x81U, 0xd1U, 0x81U,
00515                                                                                                                         0xd0U, 0xbaU, 0xd0U, 0xb8U,
00516                                                                                                                         0xd0U, 0xb9U, 0 };
00517                         const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
00518 
00519                         TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
00520                         XmlTest( "UTF-8: Browsing russian element name.",
00521                                          russianText,
00522                                          text->Value(),
00523                                          true );
00524                         XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
00525                         XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );
00526 
00527                         TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
00528                         XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
00529                         XmlTest( "UTF-8: Document column.", 1, doc.Column() );
00530 
00531                         // Now try for a round trip.
00532                         doc.SaveFile( "utf8testout.xml" );
00533 
00534                         // Check the round trip.
00535                         char savedBuf[256];
00536                         char verifyBuf[256];
00537                         int okay = 1;
00538 
00539                         FILE* saved  = fopen( "utf8testout.xml", "r" );
00540                         FILE* verify = fopen( "utf8testverify.xml", "r" );
00541                         if ( saved && verify )
00542                         {
00543                                 while ( fgets( verifyBuf, 256, verify ) )
00544                                 {
00545                                         fgets( savedBuf, 256, saved );
00546                                         if ( strcmp( verifyBuf, savedBuf ) )
00547                                         {
00548                                                 okay = 0;
00549                                                 break;
00550                                         }
00551                                 }
00552                                 fclose( saved );
00553                                 fclose( verify );
00554                         }
00555                         XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
00556 
00557                         // On most Western machines, this is an element that contains
00558                         // the word "resume" with the correct accents, in a latin encoding.
00559                         // It will be something else completely on non-wester machines,
00560                         // which is why TinyXml is switching to UTF-8.
00561                         const char latin[] = "<element>r\x82sum\x82</element>";
00562 
00563                         TiXmlDocument latinDoc;
00564                         latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );
00565 
00566                         text = latinDoc.FirstChildElement()->FirstChild()->ToText();
00567                         XmlTest( "Legacy encoding: Verify text element.", "r\x82sum\x82", text->Value() );
00568                 }
00569         }               
00570 
00571         //////////////////////
00572         // Copy and assignment
00573         //////////////////////
00574         printf ("\n** Copy and Assignment **\n");
00575         {
00576                 TiXmlElement element( "foo" );
00577                 element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );
00578 
00579                 TiXmlElement elementCopy( element );
00580                 TiXmlElement elementAssign( "foo" );
00581                 elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
00582                 elementAssign = element;
00583 
00584                 XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
00585                 XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
00586                 XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
00587                 XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
00588                 XmlTest( "Copy/Assign: element assign #3.", true, ( 0 == elementAssign.Attribute( "foo" )) );
00589 
00590                 TiXmlComment comment;
00591                 comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
00592                 TiXmlComment commentCopy( comment );
00593                 TiXmlComment commentAssign;
00594                 commentAssign = commentCopy;
00595                 XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
00596                 XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );
00597 
00598                 TiXmlUnknown unknown;
00599                 unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
00600                 TiXmlUnknown unknownCopy( unknown );
00601                 TiXmlUnknown unknownAssign;
00602                 unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
00603                 unknownAssign = unknownCopy;
00604                 XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
00605                 XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );
00606                 
00607                 TiXmlText text( "TextNode" );
00608                 TiXmlText textCopy( text );
00609                 TiXmlText textAssign( "incorrect" );
00610                 textAssign = text;
00611                 XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
00612                 XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );
00613 
00614                 TiXmlDeclaration dec;
00615                 dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
00616                 TiXmlDeclaration decCopy( dec );
00617                 TiXmlDeclaration decAssign;
00618                 decAssign = dec;
00619 
00620                 XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
00621                 XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );
00622 
00623                 TiXmlDocument doc;
00624                 elementCopy.InsertEndChild( textCopy );
00625                 doc.InsertEndChild( decAssign );
00626                 doc.InsertEndChild( elementCopy );
00627                 doc.InsertEndChild( unknownAssign );
00628 
00629                 TiXmlDocument docCopy( doc );
00630                 TiXmlDocument docAssign;
00631                 docAssign = docCopy;
00632 
00633                 #ifdef TIXML_USE_STL
00634                 std::string original, copy, assign;
00635                 original << doc;
00636                 copy << docCopy;
00637                 assign << docAssign;
00638                 XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
00639                 XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );
00640 
00641                 #endif
00642         }       
00643 
00644         //////////////////////////////////////////////////////
00645 #ifdef TIXML_USE_STL
00646         printf ("\n** Parsing, no Condense Whitespace **\n");
00647         TiXmlBase::SetCondenseWhiteSpace( false );
00648         {
00649                 istringstream parse1( "<start>This  is    \ntext</start>" );
00650                 TiXmlElement text1( "text" );
00651                 parse1 >> text1;
00652 
00653                 XmlTest ( "Condense white space OFF.", "This  is    \ntext",
00654                                         text1.FirstChild()->Value(),
00655                                         true );
00656         }
00657         TiXmlBase::SetCondenseWhiteSpace( true );
00658 #endif
00659 
00660         //////////////////////////////////////////////////////
00661         // GetText();
00662         {
00663                 const char* str = "<foo>This is text</foo>";
00664                 TiXmlDocument doc;
00665                 doc.Parse( str );
00666                 const TiXmlElement* element = doc.RootElement();
00667 
00668                 XmlTest( "GetText() normal use.", "This is text", element->GetText() );
00669 
00670                 str = "<foo><b>This is text</b></foo>";
00671                 doc.Clear();
00672                 doc.Parse( str );
00673                 element = doc.RootElement();
00674 
00675                 XmlTest( "GetText() contained element.", element->GetText() == 0, true );
00676 
00677                 str = "<foo>This is <b>text</b></foo>";
00678                 doc.Clear();
00679                 TiXmlBase::SetCondenseWhiteSpace( false );
00680                 doc.Parse( str );
00681                 TiXmlBase::SetCondenseWhiteSpace( true );
00682                 element = doc.RootElement();
00683 
00684                 XmlTest( "GetText() partial.", "This is ", element->GetText() );
00685         }
00686 
00687 
00688         //////////////////////////////////////////////////////
00689         // CDATA
00690         {
00691                 const char* str =       "<xmlElement>"
00692                                                                 "<![CDATA["
00693                                                                         "I am > the rules!\n"
00694                                                                         "...since I make symbolic puns"
00695                                                                 "]]>"
00696                                                         "</xmlElement>";
00697                 TiXmlDocument doc;
00698                 doc.Parse( str );
00699                 doc.Print();
00700 
00701                 XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), 
00702                                                                  "I am > the rules!\n...since I make symbolic puns",
00703                                                                  true );
00704 
00705                 #ifdef TIXML_USE_STL
00706                 //cout << doc << '\n';
00707 
00708                 doc.Clear();
00709 
00710                 istringstream parse0( str );
00711                 parse0 >> doc;
00712                 //cout << doc << '\n';
00713 
00714                 XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(), 
00715                                                                  "I am > the rules!\n...since I make symbolic puns",
00716                                                                  true );
00717                 #endif
00718 
00719                 TiXmlDocument doc1 = doc;
00720                 //doc.Print();
00721 
00722                 XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(), 
00723                                                                  "I am > the rules!\n...since I make symbolic puns",
00724                                                                  true );
00725         }
00726 
00727 
00728         //////////////////////////////////////////////////////
00729         printf ("\n** Bug regression tests **\n");
00730 
00731         // InsertBeforeChild and InsertAfterChild causes crash.
00732         {
00733                 TiXmlElement parent( "Parent" );
00734                 TiXmlElement childText0( "childText0" );
00735                 TiXmlElement childText1( "childText1" );
00736                 TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
00737                 TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );
00738 
00739                 XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
00740         }
00741 
00742         {
00743                 // InsertBeforeChild and InsertAfterChild causes crash.
00744                 TiXmlElement parent( "Parent" );
00745                 TiXmlElement childText0( "childText0" );
00746                 TiXmlElement childText1( "childText1" );
00747                 TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
00748                 TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );
00749 
00750                 XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
00751         }
00752 
00753         // Reports of missing constructors, irregular string problems.
00754         {
00755                 // Missing constructor implementation. No test -- just compiles.
00756                 TiXmlText text( "Missing" );
00757 
00758                 #ifdef TIXML_USE_STL
00759                         // Missing implementation:
00760                         TiXmlDocument doc;
00761                         string name = "missing";
00762                         doc.LoadFile( name );
00763 
00764                         TiXmlText textSTL( name );
00765                 #else
00766                         // verifying some basic string functions:
00767                         TiXmlString a;
00768                         TiXmlString b( "Hello" );
00769                         TiXmlString c( "ooga" );
00770 
00771                         c = " World!";
00772                         a = b;
00773                         a += c;
00774                         a = a;
00775 
00776                         XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
00777                 #endif
00778         }
00779 
00780         // Long filenames crashing STL version
00781         {
00782                 TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
00783                 bool loadOkay = doc.LoadFile();
00784                 loadOkay = true;        // get rid of compiler warning.
00785                 // Won't pass on non-dev systems. Just a "no crash" check.
00786                 //XmlTest( "Long filename. ", true, loadOkay );
00787         }
00788 
00789         {
00790                 // Entities not being written correctly.
00791                 // From Lynn Allen
00792 
00793                 const char* passages =
00794                         "<?xml version=\"1.0\" standalone=\"no\" ?>"
00795                         "<passages count=\"006\" formatversion=\"20020620\">"
00796                                 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
00797                                 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
00798                         "</passages>";
00799 
00800                 TiXmlDocument doc( "passages.xml" );
00801                 doc.Parse( passages );
00802                 TiXmlElement* psg = doc.RootElement()->FirstChildElement();
00803                 const char* context = psg->Attribute( "context" );
00804                 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
00805 
00806                 XmlTest( "Entity transformation: read. ", expected, context, true );
00807 
00808                 FILE* textfile = fopen( "textfile.txt", "w" );
00809                 if ( textfile )
00810                 {
00811                         psg->Print( textfile, 0 );
00812                         fclose( textfile );
00813                 }
00814                 textfile = fopen( "textfile.txt", "r" );
00815                 assert( textfile );
00816                 if ( textfile )
00817                 {
00818                         char buf[ 1024 ];
00819                         fgets( buf, 1024, textfile );
00820                         XmlTest( "Entity transformation: write. ",
00821                                          "<psg context=\'Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
00822                                          " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.' />",
00823                                          buf,
00824                                          true );
00825                 }
00826                 fclose( textfile );
00827         }
00828 
00829     {
00830                 FILE* textfile = fopen( "test5.xml", "w" );
00831                 if ( textfile )
00832                 {
00833             fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile);
00834             fclose(textfile);
00835 
00836                         TiXmlDocument doc;
00837             doc.LoadFile( "test5.xml" );
00838             XmlTest( "dot in element attributes and names", doc.Error(), 0);
00839                 }
00840     }
00841 
00842         {
00843                 FILE* textfile = fopen( "test6.xml", "w" );
00844                 if ( textfile )
00845                 {
00846             fputs("<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>", textfile );
00847             fclose(textfile);
00848 
00849             TiXmlDocument doc;
00850             bool result = doc.LoadFile( "test6.xml" );
00851             XmlTest( "Entity with one digit.", result, true );
00852 
00853                         TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
00854                         XmlTest( "Entity with one digit.",
00855                                                 text->Value(), "1.1 Start easy ignore fin thickness\n" );
00856                 }
00857     }
00858 
00859         {
00860                 // DOCTYPE not preserved (950171)
00861                 // 
00862                 const char* doctype =
00863                         "<?xml version=\"1.0\" ?>"
00864                         "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
00865                         "<!ELEMENT title (#PCDATA)>"
00866                         "<!ELEMENT books (title,authors)>"
00867                         "<element />";
00868 
00869                 TiXmlDocument doc;
00870                 doc.Parse( doctype );
00871                 doc.SaveFile( "test7.xml" );
00872                 doc.Clear();
00873                 doc.LoadFile( "test7.xml" );
00874                 
00875                 TiXmlHandle docH( &doc );
00876                 TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
00877                 XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
00878                 #ifdef TIXML_USE_STL
00879                 TiXmlNode* node = docH.Child( 2 ).Node();
00880                 std::string str;
00881                 str << (*node);
00882                 XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
00883                 #endif
00884         }
00885 
00886         {
00887                 // [ 791411 ] Formatting bug
00888                 // Comments do not stream out correctly.
00889                 const char* doctype = 
00890                         "<!-- Somewhat<evil> -->";
00891                 TiXmlDocument doc;
00892                 doc.Parse( doctype );
00893 
00894                 TiXmlHandle docH( &doc );
00895                 TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();
00896 
00897                 XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
00898                 #ifdef TIXML_USE_STL
00899                 std::string str;
00900                 str << (*comment);
00901                 XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
00902                 #endif
00903         }
00904 
00905         {
00906                 // [ 870502 ] White space issues
00907                 TiXmlDocument doc;
00908                 TiXmlText* text;
00909                 TiXmlHandle docH( &doc );
00910         
00911                 const char* doctype0 = "<element> This has leading and trailing space </element>";
00912                 const char* doctype1 = "<element>This has  internal space</element>";
00913                 const char* doctype2 = "<element> This has leading, trailing, and  internal space </element>";
00914 
00915                 TiXmlBase::SetCondenseWhiteSpace( false );
00916                 doc.Clear();
00917                 doc.Parse( doctype0 );
00918                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00919                 XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );
00920 
00921                 doc.Clear();
00922                 doc.Parse( doctype1 );
00923                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00924                 XmlTest( "White space kept.", "This has  internal space", text->Value() );
00925 
00926                 doc.Clear();
00927                 doc.Parse( doctype2 );
00928                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00929                 XmlTest( "White space kept.", " This has leading, trailing, and  internal space ", text->Value() );
00930 
00931                 TiXmlBase::SetCondenseWhiteSpace( true );
00932                 doc.Clear();
00933                 doc.Parse( doctype0 );
00934                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00935                 XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );
00936 
00937                 doc.Clear();
00938                 doc.Parse( doctype1 );
00939                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00940                 XmlTest( "White space condensed.", "This has internal space", text->Value() );
00941 
00942                 doc.Clear();
00943                 doc.Parse( doctype2 );
00944                 text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
00945                 XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
00946         }
00947 
00948         {
00949                 // Double attributes
00950                 const char* doctype = "<element attr='red' attr='blue' />";
00951 
00952                 TiXmlDocument doc;
00953                 doc.Parse( doctype );
00954                 
00955                 XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an  error to tinyxml
00956                 XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
00957         }
00958 
00959         {
00960                 // Embedded null in stream.
00961                 const char* doctype = "<element att\0r='red' attr='blue' />";
00962 
00963                 TiXmlDocument doc;
00964                 doc.Parse( doctype );
00965                 XmlTest( "Embedded null throws error.", true, doc.Error() );
00966 
00967                 #ifdef TIXML_USE_STL
00968                 istringstream strm( doctype );
00969                 doc.Clear();
00970                 doc.ClearError();
00971                 strm >> doc;
00972                 XmlTest( "Embedded null throws error.", true, doc.Error() );
00973                 #endif
00974         }
00975 
00976     {
00977             // Legacy mode test. (This test may only pass on a western system)
00978             const char* str =
00979                         "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"
00980                         "<ä>"
00981                         "CöntäntßäöüÄÖÜ"
00982                         "</ä>";
00983 
00984             TiXmlDocument doc;
00985             doc.Parse( str );
00986 
00987                         //doc.Print( stdout, 0 );
00988 
00989             TiXmlHandle docHandle( &doc );
00990             TiXmlHandle aHandle = docHandle.FirstChildElement( "ä" );
00991             TiXmlHandle tHandle = aHandle.Child( 0 );
00992             assert( aHandle.Element() );
00993             assert( tHandle.Text() );
00994             XmlTest( "ISO-8859-1 Parsing.", "CöntäntßäöüÄÖÜ", tHandle.Text()->Value() );
00995     }
00996 
00997         {
00998                 // Empty documents should return TIXML_ERROR_PARSING_EMPTY, bug 1070717
00999                 const char* str = "    ";
01000                 TiXmlDocument doc;
01001                 doc.Parse( str );
01002                 XmlTest( "Empty document error TIXML_ERROR_DOCUMENT_EMPTY", TiXmlBase::TIXML_ERROR_DOCUMENT_EMPTY, doc.ErrorId() );
01003         }
01004         #ifndef TIXML_USE_STL
01005         {
01006                 // String equality. [ 1006409 ] string operator==/!= no worky in all cases
01007                 TiXmlString temp;
01008                 XmlTest( "Empty tinyxml string compare equal", ( temp == "" ), true );
01009 
01010                 TiXmlString    foo;
01011                 TiXmlString    bar( "" );
01012                 XmlTest( "Empty tinyxml string compare equal", ( foo == bar ), true );
01013         }
01014 
01015         #endif
01016         {
01017                 // Bug [ 1195696 ] from marlonism
01018                 TiXmlBase::SetCondenseWhiteSpace(false); 
01019                 TiXmlDocument xml; 
01020                 xml.Parse("<text><break/>This hangs</text>"); 
01021                 XmlTest( "Test safe error return.", xml.Error(), false );
01022         }
01023 
01024         {
01025                 // Bug [ 1243992 ] - another infinite loop
01026                 TiXmlDocument doc;
01027                 doc.SetCondenseWhiteSpace(false);
01028                 doc.Parse("<p><pb></pb>test</p>");
01029         } 
01030         {
01031                 // Low entities
01032                 TiXmlDocument xml;
01033                 xml.Parse( "<test>&#x0e;</test>" );
01034                 const char result[] = { 0x0e, 0 };
01035                 XmlTest( "Low entities.", xml.FirstChildElement()->GetText(), result );
01036                 xml.Print();
01037         }
01038 
01039         #if defined( WIN32 ) && defined( TUNE )
01040         _CrtMemCheckpoint( &endMemState );
01041         //_CrtMemDumpStatistics( &endMemState );
01042 
01043         _CrtMemState diffMemState;
01044         _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
01045         _CrtMemDumpStatistics( &diffMemState );
01046         #endif
01047 
01048         printf ("\nPass %d, Fail %d\n", gPass, gFail);
01049         return gFail;
01050 }
01051 
01052 

Generated on Wed Sep 5 12:54:28 2007 for DSACSS Operational Code by  doxygen 1.3.9.1