blob: 152c588575bc48cab2e4dbbb4eb8ffe0acd63655 [file] [log] [blame]
Lee Thomason5b0a6772012-11-19 13:54:42 -08001#if defined( _MSC_VER )
2 #define _CRT_SECURE_NO_WARNINGS // This test file is not intended to be secure.
3#endif
U-Lama\Leee13c3e62011-12-28 14:36:55 -08004
Lee Thomason5b0a6772012-11-19 13:54:42 -08005#include "tinyxml2.h"
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -07006#include <cstdlib>
7#include <cstring>
8#include <ctime>
U-Lama\Leee13c3e62011-12-28 14:36:55 -08009
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -080010#if defined( _MSC_VER )
Lee Thomasone9699e62012-07-25 12:24:23 -070011 #include <direct.h> // _mkdir
Lee Thomason1ff38e02012-02-14 18:18:16 -080012 #include <crtdbg.h>
Lee Thomason6f381b72012-03-02 12:59:39 -080013 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
Lee Thomason1ff38e02012-02-14 18:18:16 -080015 _CrtMemState startMemState;
16 _CrtMemState endMemState;
Lee Thomasone9699e62012-07-25 12:24:23 -070017#else
18 #include <sys/stat.h> // mkdir
Lee Thomason1ff38e02012-02-14 18:18:16 -080019#endif
Lee Thomasone9ecdab2012-02-13 18:11:20 -080020
U-Lama\Leee13c3e62011-12-28 14:36:55 -080021using namespace tinyxml2;
Lee Thomasonec5a7b42012-02-13 18:16:52 -080022int gPass = 0;
23int gFail = 0;
24
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -080025
U-Stream\Lee09a11c52012-02-17 08:31:16 -080026bool XMLTest (const char* testString, const char* expected, const char* found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080027{
28 bool pass = !strcmp( expected, found );
29 if ( pass )
30 printf ("[pass]");
31 else
32 printf ("[fail]");
33
U-Stream\Lee09a11c52012-02-17 08:31:16 -080034 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080035 printf (" %s\n", testString);
36 else
37 printf (" %s [%s][%s]\n", testString, expected, found);
38
39 if ( pass )
40 ++gPass;
41 else
42 ++gFail;
43 return pass;
44}
45
46
Lee Thomason21be8822012-07-15 17:27:22 -070047template< class T > bool XMLTest( const char* testString, T expected, T found, bool echo=true )
Lee Thomason1ff38e02012-02-14 18:18:16 -080048{
49 bool pass = ( expected == found );
50 if ( pass )
51 printf ("[pass]");
52 else
53 printf ("[fail]");
54
U-Stream\Lee09a11c52012-02-17 08:31:16 -080055 if ( !echo )
Lee Thomason1ff38e02012-02-14 18:18:16 -080056 printf (" %s\n", testString);
57 else
Lee Thomasonc8312792012-07-16 12:44:41 -070058 printf (" %s [%d][%d]\n", testString, static_cast<int>(expected), static_cast<int>(found) );
Lee Thomason1ff38e02012-02-14 18:18:16 -080059
60 if ( pass )
61 ++gPass;
62 else
63 ++gFail;
64 return pass;
65}
Lee Thomasonec5a7b42012-02-13 18:16:52 -080066
U-Lama\Leee13c3e62011-12-28 14:36:55 -080067
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -080068void NullLineEndings( char* p )
69{
70 while( p && *p ) {
71 if ( *p == '\n' || *p == '\r' ) {
72 *p = 0;
73 return;
74 }
75 ++p;
76 }
77}
78
79
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -070080// Comments in the header. (Don't know how to get Doxygen to read comments in this file.)
81int example_1()
82{
83 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -030084 doc.LoadFile( "resources/dream.xml" );
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -070085
86 return doc.ErrorID();
87}
88
89
90// Comments in the header. (Don't know how to get Doxygen to read comments in this file.)
91int example_2()
92{
93 static const char* xml = "<element/>";
94 XMLDocument doc;
95 doc.Parse( xml );
96
97 return doc.ErrorID();
98}
99
100
101int example_3()
102{
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700103 static const char* xml =
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700104 "<?xml version=\"1.0\"?>"
105 "<!DOCTYPE PLAY SYSTEM \"play.dtd\">"
106 "<PLAY>"
107 "<TITLE>A Midsummer Night's Dream</TITLE>"
108 "</PLAY>";
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700109
110 XMLDocument doc;
111 doc.Parse( xml );
112
113 XMLElement* titleElement = doc.FirstChildElement( "PLAY" )->FirstChildElement( "TITLE" );
114 const char* title = titleElement->GetText();
115 printf( "Name of play (1): %s\n", title );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700116
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700117 XMLText* textNode = titleElement->FirstChild()->ToText();
118 title = textNode->Value();
119 printf( "Name of play (2): %s\n", title );
120
121 return doc.ErrorID();
122}
123
124
Lee Thomason21be8822012-07-15 17:27:22 -0700125bool example_4()
126{
127 static const char* xml =
128 "<information>"
129 " <attributeApproach v='2' />"
130 " <textApproach>"
131 " <v>2</v>"
132 " </textApproach>"
133 "</information>";
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700134
Lee Thomason21be8822012-07-15 17:27:22 -0700135 XMLDocument doc;
136 doc.Parse( xml );
137
138 int v0 = 0;
139 int v1 = 0;
140
141 XMLElement* attributeApproachElement = doc.FirstChildElement()->FirstChildElement( "attributeApproach" );
142 attributeApproachElement->QueryIntAttribute( "v", &v0 );
143
144 XMLElement* textApproachElement = doc.FirstChildElement()->FirstChildElement( "textApproach" );
145 textApproachElement->FirstChildElement( "v" )->QueryIntText( &v1 );
146
147 printf( "Both values are the same: %d and %d\n", v0, v1 );
148
149 return !doc.Error() && ( v0 == v1 );
150}
151
152
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -0700153int main( int /*argc*/, const char ** /*argv*/ )
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800154{
Lee Thomason (grinliz)0a4df402012-02-27 20:50:52 -0800155 #if defined( _MSC_VER ) && defined( DEBUG )
Lee Thomason1ff38e02012-02-14 18:18:16 -0800156 _CrtMemCheckpoint( &startMemState );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700157 #endif
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800158
Lee Thomason7f7b1622012-03-24 12:49:03 -0700159 #if defined(_MSC_VER)
Lee Thomasone9699e62012-07-25 12:24:23 -0700160 _mkdir( "resources/out/" );
161 #else
162 mkdir( "resources/out/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
163 #endif
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400164
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300165 FILE* fp = fopen( "resources/dream.xml", "r" );
Lee Thomason7f7b1622012-03-24 12:49:03 -0700166 if ( !fp ) {
167 printf( "Error opening test file 'dream.xml'.\n"
168 "Is your working directory the same as where \n"
169 "the xmltest.cpp and dream.xml file are?\n\n"
170 #if defined( _MSC_VER )
171 "In windows Visual Studio you may need to set\n"
172 "Properties->Debugging->Working Directory to '..'\n"
173 #endif
174 );
175 exit( 1 );
176 }
177 fclose( fp );
178
Lee Thomason (grinliz)6a22be22012-04-04 12:39:05 -0700179 XMLTest( "Example-1", 0, example_1() );
180 XMLTest( "Example-2", 0, example_2() );
181 XMLTest( "Example-3", 0, example_3() );
Lee Thomason21be8822012-07-15 17:27:22 -0700182 XMLTest( "Example-4", true, example_4() );
Lee Thomason87e475a2012-03-20 11:55:29 -0700183
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700184 /* ------ Example 2: Lookup information. ---- */
Lee Thomason87e475a2012-03-20 11:55:29 -0700185
Lee Thomason8a5dfee2012-01-18 17:43:40 -0800186 {
Lee Thomason43f59302012-02-06 18:18:11 -0800187 static const char* test[] = { "<element />",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400188 "<element></element>",
Lee Thomason43f59302012-02-06 18:18:11 -0800189 "<element><subelement/></element>",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400190 "<element><subelement></subelement></element>",
191 "<element><subelement><subsub/></subelement></element>",
192 "<!--comment beside elements--><element><subelement></subelement></element>",
193 "<!--comment beside elements, this time with spaces--> \n <element> <subelement> \n </subelement> </element>",
194 "<element attrib1='foo' attrib2=\"bar\" ></element>",
195 "<element attrib1='foo' attrib2=\"bar\" ><subelement attrib3='yeehaa' /></element>",
Lee Thomason43f59302012-02-06 18:18:11 -0800196 "<element>Text inside element.</element>",
197 "<element><b></b></element>",
198 "<element>Text inside and <b>bolded</b> in the element.</element>",
199 "<outer><element>Text inside and <b>bolded</b> in the element.</element></outer>",
Lee Thomason8ee79892012-01-25 17:44:30 -0800200 "<element>This &amp; That.</element>",
Lee Thomason18d68bd2012-01-26 18:17:26 -0800201 "<element attrib='This&lt;That' />",
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800202 0
203 };
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800204 for( int i=0; test[i]; ++i ) {
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800205 XMLDocument doc;
Lee Thomason6ee99fc2012-01-21 18:45:16 -0800206 doc.Parse( test[i] );
Lee Thomason5cae8972012-01-24 18:03:07 -0800207 doc.Print();
Lee Thomasonec975ce2012-01-23 11:42:06 -0800208 printf( "----------------------------------------------\n" );
Lee Thomasondadcdfa2012-01-18 17:55:48 -0800209 }
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800210 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800211#if 1
Lee Thomasond6277762012-02-22 16:00:12 -0800212 {
213 static const char* test = "<!--hello world\n"
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400214 " line 2\r"
215 " line 3\r\n"
216 " line 4\n\r"
217 " line 5\r-->";
Lee Thomasond6277762012-02-22 16:00:12 -0800218
219 XMLDocument doc;
220 doc.Parse( test );
221 doc.Print();
222 }
223
Lee Thomason2c85a712012-01-31 08:24:24 -0800224 {
225 static const char* test = "<element>Text before.</element>";
226 XMLDocument doc;
227 doc.Parse( test );
228 XMLElement* root = doc.FirstChildElement();
229 XMLElement* newElement = doc.NewElement( "Subelement" );
230 root->InsertEndChild( newElement );
231 doc.Print();
232 }
Lee Thomasond1983222012-02-06 08:41:24 -0800233 {
234 XMLDocument* doc = new XMLDocument();
235 static const char* test = "<element><sub/></element>";
236 doc->Parse( test );
237 delete doc;
238 }
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800239 {
Lee Thomason1ff38e02012-02-14 18:18:16 -0800240 // Test: Programmatic DOM
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800241 // Build:
242 // <element>
243 // <!--comment-->
244 // <sub attrib="1" />
245 // <sub attrib="2" />
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800246 // <sub attrib="3" >& Text!</sub>
Lee Thomasonec5a7b42012-02-13 18:16:52 -0800247 // <element>
248
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800249 XMLDocument* doc = new XMLDocument();
Lee Thomason1ff38e02012-02-14 18:18:16 -0800250 XMLNode* element = doc->InsertEndChild( doc->NewElement( "element" ) );
251
252 XMLElement* sub[3] = { doc->NewElement( "sub" ), doc->NewElement( "sub" ), doc->NewElement( "sub" ) };
253 for( int i=0; i<3; ++i ) {
254 sub[i]->SetAttribute( "attrib", i );
255 }
256 element->InsertEndChild( sub[2] );
257 XMLNode* comment = element->InsertFirstChild( doc->NewComment( "comment" ) );
258 element->InsertAfterChild( comment, sub[0] );
259 element->InsertAfterChild( sub[0], sub[1] );
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800260 sub[2]->InsertFirstChild( doc->NewText( "& Text!" ));
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800261 doc->Print();
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800262 XMLTest( "Programmatic DOM", "comment", doc->FirstChildElement( "element" )->FirstChild()->Value() );
263 XMLTest( "Programmatic DOM", "0", doc->FirstChildElement( "element" )->FirstChildElement()->Attribute( "attrib" ) );
264 XMLTest( "Programmatic DOM", 2, doc->FirstChildElement()->LastChildElement( "sub" )->IntAttribute( "attrib" ) );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700265 XMLTest( "Programmatic DOM", "& Text!",
U-Stream\Lee09a11c52012-02-17 08:31:16 -0800266 doc->FirstChildElement()->LastChildElement( "sub" )->FirstChild()->ToText()->Value() );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800267
268 // And now deletion:
269 element->DeleteChild( sub[2] );
270 doc->DeleteNode( comment );
271
272 element->FirstChildElement()->SetAttribute( "attrib", true );
273 element->LastChildElement()->DeleteAttribute( "attrib" );
274
275 XMLTest( "Programmatic DOM", true, doc->FirstChildElement()->FirstChildElement()->BoolAttribute( "attrib" ) );
276 int value = 10;
277 int result = doc->FirstChildElement()->LastChildElement()->QueryIntAttribute( "attrib", &value );
Lee Thomason21be8822012-07-15 17:27:22 -0700278 XMLTest( "Programmatic DOM", result, (int)XML_NO_ATTRIBUTE );
U-Stream\Leeae25a442012-02-17 17:48:16 -0800279 XMLTest( "Programmatic DOM", value, 10 );
280
281 doc->Print();
282
Lee Thomason7b1b86a2012-06-04 17:01:38 -0700283 {
284 XMLPrinter streamer;
285 doc->Print( &streamer );
286 printf( "%s", streamer.CStr() );
287 }
288 {
289 XMLPrinter streamer( 0, true );
290 doc->Print( &streamer );
291 XMLTest( "Compact mode", "<element><sub attrib=\"1\"/><sub/></element>", streamer.CStr(), false );
292 }
Lee Thomason (grinliz)6b8b0122012-09-08 21:21:00 -0700293 doc->SaveFile( "./resources/out/pretty.xml" );
294 doc->SaveFile( "./resources/out/compact.xml", true );
Lee Thomasone9ecdab2012-02-13 18:11:20 -0800295 delete doc;
296 }
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800297 {
298 // Test: Dream
299 // XML1 : 1,187,569 bytes in 31,209 allocations
300 // XML2 : 469,073 bytes in 323 allocations
301 //int newStart = gNew;
302 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300303 doc.LoadFile( "resources/dream.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800304
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400305 doc.SaveFile( "resources/out/dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800306 doc.PrintError();
307
308 XMLTest( "Dream", "xml version=\"1.0\"",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400309 doc.FirstChild()->ToDeclaration()->Value() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800310 XMLTest( "Dream", true, doc.FirstChild()->NextSibling()->ToUnknown() ? true : false );
311 XMLTest( "Dream", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
312 doc.FirstChild()->NextSibling()->ToUnknown()->Value() );
313 XMLTest( "Dream", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400314 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800315 XMLTest( "Dream", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400316 doc.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800317
318 XMLDocument doc2;
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400319 doc2.LoadFile( "resources/out/dreamout.xml" );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800320 XMLTest( "Dream-out", "xml version=\"1.0\"",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400321 doc2.FirstChild()->ToDeclaration()->Value() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800322 XMLTest( "Dream-out", true, doc2.FirstChild()->NextSibling()->ToUnknown() ? true : false );
323 XMLTest( "Dream-out", "DOCTYPE PLAY SYSTEM \"play.dtd\"",
324 doc2.FirstChild()->NextSibling()->ToUnknown()->Value() );
325 XMLTest( "Dream-out", "And Robin shall restore amends.",
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400326 doc2.LastChild()->LastChild()->LastChild()->LastChild()->LastChildElement()->GetText() );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -0800327
328 //gNewTotal = gNew - newStart;
329 }
Lee Thomason6f381b72012-03-02 12:59:39 -0800330
331
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800332 {
333 const char* error = "<?xml version=\"1.0\" standalone=\"no\" ?>\n"
334 "<passages count=\"006\" formatversion=\"20020620\">\n"
335 " <wrong error>\n"
336 "</passages>";
337
338 XMLDocument doc;
339 doc.Parse( error );
Lee Thomason2fa81722012-11-09 12:37:46 -0800340 XMLTest( "Bad XML", doc.ErrorID(), XML_ERROR_PARSING_ATTRIBUTE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800341 }
342
343 {
344 const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
345
346 XMLDocument doc;
347 doc.Parse( str );
348
349 XMLElement* ele = doc.FirstChildElement();
350
351 int iVal, result;
352 double dVal;
353
354 result = ele->QueryDoubleAttribute( "attr0", &dVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700355 XMLTest( "Query attribute: int as double", result, (int)XML_NO_ERROR );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800356 XMLTest( "Query attribute: int as double", (int)dVal, 1 );
357 result = ele->QueryDoubleAttribute( "attr1", &dVal );
358 XMLTest( "Query attribute: double as double", (int)dVal, 2 );
359 result = ele->QueryIntAttribute( "attr1", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700360 XMLTest( "Query attribute: double as int", result, (int)XML_NO_ERROR );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800361 XMLTest( "Query attribute: double as int", iVal, 2 );
362 result = ele->QueryIntAttribute( "attr2", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700363 XMLTest( "Query attribute: not a number", result, (int)XML_WRONG_ATTRIBUTE_TYPE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800364 result = ele->QueryIntAttribute( "bar", &iVal );
Lee Thomason21be8822012-07-15 17:27:22 -0700365 XMLTest( "Query attribute: does not exist", result, (int)XML_NO_ATTRIBUTE );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800366 }
367
368 {
369 const char* str = "<doc/>";
370
371 XMLDocument doc;
372 doc.Parse( str );
373
374 XMLElement* ele = doc.FirstChildElement();
375
376 int iVal;
377 double dVal;
378
379 ele->SetAttribute( "str", "strValue" );
380 ele->SetAttribute( "int", 1 );
381 ele->SetAttribute( "double", -1.0 );
382
383 const char* cStr = ele->Attribute( "str" );
384 ele->QueryIntAttribute( "int", &iVal );
385 ele->QueryDoubleAttribute( "double", &dVal );
386
Lee Thomason8ba7f7d2012-03-24 13:04:04 -0700387 XMLTest( "Attribute match test", ele->Attribute( "str", "strValue" ), "strValue" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800388 XMLTest( "Attribute round trip. c-string.", "strValue", cStr );
389 XMLTest( "Attribute round trip. int.", 1, iVal );
390 XMLTest( "Attribute round trip. double.", -1, (int)dVal );
391 }
392
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800393 {
394 XMLDocument doc;
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300395 doc.LoadFile( "resources/utf8test.xml" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800396
397 // Get the attribute "value" from the "Russian" element and check it.
398 XMLElement* element = doc.FirstChildElement( "document" )->FirstChildElement( "Russian" );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700399 const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU,
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800400 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
401
402 XMLTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ) );
403
404 const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
405 0xd1U, 0x81U, 0xd1U, 0x81U,
406 0xd0U, 0xbaU, 0xd0U, 0xb8U,
407 0xd0U, 0xb9U, 0 };
408 const char russianText[] = "<\xD0\xB8\xD0\xBC\xD0\xB5\xD0\xB5\xD1\x82>";
409
410 XMLText* text = doc.FirstChildElement( "document" )->FirstChildElement( (const char*) russianElementName )->FirstChild()->ToText();
411 XMLTest( "UTF-8: Browsing russian element name.",
412 russianText,
413 text->Value() );
414
415 // Now try for a round trip.
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400416 doc.SaveFile( "resources/out/utf8testout.xml" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800417
418 // Check the round trip.
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800419 int okay = 0;
420
Thomas Roßa6dd8c62012-07-26 20:42:18 +0200421 FILE* saved = fopen( "resources/out/utf8testout.xml", "r" );
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300422 FILE* verify = fopen( "resources/utf8testverify.xml", "r" );
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800423
424 if ( saved && verify )
425 {
426 okay = 1;
PKEuSc28ba3a2012-07-16 03:08:47 -0700427 char verifyBuf[256];
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800428 while ( fgets( verifyBuf, 256, verify ) )
429 {
PKEuSc28ba3a2012-07-16 03:08:47 -0700430 char savedBuf[256];
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800431 fgets( savedBuf, 256, saved );
432 NullLineEndings( verifyBuf );
433 NullLineEndings( savedBuf );
434
435 if ( strcmp( verifyBuf, savedBuf ) )
436 {
437 printf( "verify:%s<\n", verifyBuf );
438 printf( "saved :%s<\n", savedBuf );
439 okay = 0;
440 break;
441 }
442 }
443 }
444 if ( saved )
445 fclose( saved );
446 if ( verify )
447 fclose( verify );
448 XMLTest( "UTF-8: Verified multi-language round trip.", 1, okay );
449 }
450
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800451 // --------GetText()-----------
452 {
453 const char* str = "<foo>This is text</foo>";
454 XMLDocument doc;
455 doc.Parse( str );
456 const XMLElement* element = doc.RootElement();
457
458 XMLTest( "GetText() normal use.", "This is text", element->GetText() );
459
460 str = "<foo><b>This is text</b></foo>";
461 doc.Parse( str );
462 element = doc.RootElement();
463
464 XMLTest( "GetText() contained element.", element->GetText() == 0, true );
465 }
Lee Thomason (grinliz)68db57e2012-02-21 09:08:12 -0800466
Lee Thomasond6277762012-02-22 16:00:12 -0800467
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800468 // ---------- CDATA ---------------
469 {
470 const char* str = "<xmlElement>"
471 "<![CDATA["
472 "I am > the rules!\n"
473 "...since I make symbolic puns"
474 "]]>"
475 "</xmlElement>";
476 XMLDocument doc;
477 doc.Parse( str );
478 doc.Print();
Lee Thomasond6277762012-02-22 16:00:12 -0800479
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700480 XMLTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(),
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800481 "I am > the rules!\n...since I make symbolic puns",
Lee Thomasond6277762012-02-22 16:00:12 -0800482 false );
483 }
484
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800485 // ----------- CDATA -------------
486 {
487 const char* str = "<xmlElement>"
488 "<![CDATA["
489 "<b>I am > the rules!</b>\n"
490 "...since I make symbolic puns"
491 "]]>"
492 "</xmlElement>";
493 XMLDocument doc;
494 doc.Parse( str );
495 doc.Print();
496
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700497 XMLTest( "CDATA parse. [ tixml1:1480107 ]", doc.FirstChildElement()->FirstChild()->Value(),
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800498 "<b>I am > the rules!</b>\n...since I make symbolic puns",
499 false );
500 }
501
502 // InsertAfterChild causes crash.
503 {
504 // InsertBeforeChild and InsertAfterChild causes crash.
505 XMLDocument doc;
506 XMLElement* parent = doc.NewElement( "Parent" );
507 doc.InsertFirstChild( parent );
508
509 XMLElement* childText0 = doc.NewElement( "childText0" );
510 XMLElement* childText1 = doc.NewElement( "childText1" );
511
512 XMLNode* childNode0 = parent->InsertEndChild( childText0 );
513 XMLNode* childNode1 = parent->InsertAfterChild( childNode0, childText1 );
514
515 XMLTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent->LastChild() ), true );
516 }
Lee Thomasond6277762012-02-22 16:00:12 -0800517
518 {
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800519 // Entities not being written correctly.
520 // From Lynn Allen
Lee Thomasond6277762012-02-22 16:00:12 -0800521
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800522 const char* passages =
523 "<?xml version=\"1.0\" standalone=\"no\" ?>"
524 "<passages count=\"006\" formatversion=\"20020620\">"
525 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
526 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;.\"> </psg>"
527 "</passages>";
Lee Thomasond6277762012-02-22 16:00:12 -0800528
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800529 XMLDocument doc;
530 doc.Parse( passages );
531 XMLElement* psg = doc.RootElement()->FirstChildElement();
532 const char* context = psg->Attribute( "context" );
533 const char* expected = "Line 5 has \"quotation marks\" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright \xC2\xA9.";
Lee Thomasond6277762012-02-22 16:00:12 -0800534
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800535 XMLTest( "Entity transformation: read. ", expected, context, true );
Lee Thomasond6277762012-02-22 16:00:12 -0800536
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400537 FILE* textfile = fopen( "resources/out/textfile.txt", "w" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800538 if ( textfile )
539 {
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800540 XMLPrinter streamer( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800541 psg->Accept( &streamer );
542 fclose( textfile );
543 }
Thomas Roß0922b732012-09-23 16:31:22 +0200544
545 textfile = fopen( "resources/out/textfile.txt", "r" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800546 TIXMLASSERT( textfile );
547 if ( textfile )
548 {
549 char buf[ 1024 ];
550 fgets( buf, 1024, textfile );
551 XMLTest( "Entity transformation: write. ",
552 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
553 " It also has &lt;, &gt;, and &amp;, as well as a fake copyright \xC2\xA9.\"/>\n",
554 buf, false );
PKEuSc28ba3a2012-07-16 03:08:47 -0700555 fclose( textfile );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800556 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800557 }
558
559 {
Lee Thomason6f381b72012-03-02 12:59:39 -0800560 // Suppress entities.
561 const char* passages =
562 "<?xml version=\"1.0\" standalone=\"no\" ?>"
563 "<passages count=\"006\" formatversion=\"20020620\">"
564 "<psg context=\"Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;.\">Crazy &ttk;</psg>"
565 "</passages>";
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700566
Lee Thomason6f381b72012-03-02 12:59:39 -0800567 XMLDocument doc( false );
568 doc.Parse( passages );
569
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700570 XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->Attribute( "context" ),
Lee Thomason6f381b72012-03-02 12:59:39 -0800571 "Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;." );
572 XMLTest( "No entity parsing.", doc.FirstChildElement()->FirstChildElement()->FirstChild()->Value(),
573 "Crazy &ttk;" );
574 doc.Print();
575 }
576
577 {
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400578 const char* test = "<?xml version='1.0'?><a.elem xmi.version='2.0'/>";
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800579
580 XMLDocument doc;
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400581 doc.Parse( test );
582 XMLTest( "dot in names", doc.Error(), false );
583 XMLTest( "dot in names", doc.FirstChildElement()->Name(), "a.elem" );
584 XMLTest( "dot in names", doc.FirstChildElement()->Attribute( "xmi.version" ), "2.0" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800585 }
586
587 {
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400588 const char* test = "<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>";
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800589
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400590 XMLDocument doc;
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800591 doc.Parse( test );
592
593 XMLText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
594 XMLTest( "Entity with one digit.",
595 text->Value(), "1.1 Start easy ignore fin thickness\n",
596 false );
Arkadiy Shapkinef1c69c2012-07-25 22:10:39 +0400597 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800598
599 {
600 // DOCTYPE not preserved (950171)
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700601 //
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800602 const char* doctype =
603 "<?xml version=\"1.0\" ?>"
604 "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
605 "<!ELEMENT title (#PCDATA)>"
606 "<!ELEMENT books (title,authors)>"
607 "<element />";
608
609 XMLDocument doc;
610 doc.Parse( doctype );
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400611 doc.SaveFile( "resources/out/test7.xml" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800612 doc.DeleteChild( doc.RootElement() );
Arkadiy Shapkinff72d1f2012-07-24 00:24:07 +0400613 doc.LoadFile( "resources/out/test7.xml" );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800614 doc.Print();
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700615
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800616 const XMLUnknown* decl = doc.FirstChild()->NextSibling()->ToUnknown();
617 XMLTest( "Correct value of unknown.", "DOCTYPE PLAY SYSTEM 'play.dtd'", decl->Value() );
618
619 }
620
621 {
622 // Comments do not stream out correctly.
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700623 const char* doctype =
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800624 "<!-- Somewhat<evil> -->";
625 XMLDocument doc;
626 doc.Parse( doctype );
627
628 XMLComment* comment = doc.FirstChild()->ToComment();
629
630 XMLTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
631 }
632 {
633 // Double attributes
634 const char* doctype = "<element attr='red' attr='blue' />";
635
636 XMLDocument doc;
637 doc.Parse( doctype );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700638
Lee Thomason2fa81722012-11-09 12:37:46 -0800639 XMLTest( "Parsing repeated attributes.", XML_ERROR_PARSING_ATTRIBUTE, doc.ErrorID() ); // is an error to tinyxml (didn't use to be, but caused issues)
Lee Thomason (grinliz)0a4df402012-02-27 20:50:52 -0800640 doc.PrintError();
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800641 }
642
643 {
644 // Embedded null in stream.
645 const char* doctype = "<element att\0r='red' attr='blue' />";
646
647 XMLDocument doc;
648 doc.Parse( doctype );
649 XMLTest( "Embedded null throws error.", true, doc.Error() );
650 }
651
652 {
Guillermo A. Amaral2eb70032012-03-20 11:26:57 -0700653 // Empty documents should return TIXML_XML_ERROR_PARSING_EMPTY, bug 1070717
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800654 const char* str = " ";
655 XMLDocument doc;
656 doc.Parse( str );
Lee Thomason2fa81722012-11-09 12:37:46 -0800657 XMLTest( "Empty document error", XML_ERROR_EMPTY_DOCUMENT, doc.ErrorID() );
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800658 }
659
660 {
661 // Low entities
662 XMLDocument doc;
663 doc.Parse( "<test>&#x0e;</test>" );
664 const char result[] = { 0x0e, 0 };
665 XMLTest( "Low entities.", doc.FirstChildElement()->GetText(), result );
666 doc.Print();
667 }
668
669 {
670 // Attribute values with trailing quotes not handled correctly
671 XMLDocument doc;
672 doc.Parse( "<foo attribute=bar\" />" );
673 XMLTest( "Throw error with bad end quotes.", doc.Error(), true );
674 }
675
676 {
677 // [ 1663758 ] Failure to report error on bad XML
678 XMLDocument xml;
679 xml.Parse("<x>");
680 XMLTest("Missing end tag at end of input", xml.Error(), true);
681 xml.Parse("<x> ");
682 XMLTest("Missing end tag with trailing whitespace", xml.Error(), true);
683 xml.Parse("<x></y>");
Lee Thomason2fa81722012-11-09 12:37:46 -0800684 XMLTest("Mismatched tags", xml.ErrorID(), XML_ERROR_MISMATCHED_ELEMENT);
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700685 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800686
687
688 {
689 // [ 1475201 ] TinyXML parses entities in comments
690 XMLDocument xml;
691 xml.Parse("<!-- declarations for <head> & <body> -->"
692 "<!-- far &amp; away -->" );
693
694 XMLNode* e0 = xml.FirstChild();
695 XMLNode* e1 = e0->NextSibling();
696 XMLComment* c0 = e0->ToComment();
697 XMLComment* c1 = e1->ToComment();
698
699 XMLTest( "Comments ignore entities.", " declarations for <head> & <body> ", c0->Value(), true );
700 XMLTest( "Comments ignore entities.", " far &amp; away ", c1->Value(), true );
701 }
702
703 {
704 XMLDocument xml;
705 xml.Parse( "<Parent>"
706 "<child1 att=''/>"
707 "<!-- With this comment, child2 will not be parsed! -->"
708 "<child2 att=''/>"
709 "</Parent>" );
710 xml.Print();
711
712 int count = 0;
713
714 for( XMLNode* ele = xml.FirstChildElement( "Parent" )->FirstChild();
715 ele;
716 ele = ele->NextSibling() )
717 {
718 ++count;
719 }
720
721 XMLTest( "Comments iterate correctly.", 3, count );
722 }
723
724 {
725 // trying to repro ]1874301]. If it doesn't go into an infinite loop, all is well.
726 unsigned char buf[] = "<?xml version=\"1.0\" encoding=\"utf-8\"?><feed><![CDATA[Test XMLblablablalblbl";
727 buf[60] = 239;
728 buf[61] = 0;
729
730 XMLDocument doc;
731 doc.Parse( (const char*)buf);
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700732 }
Lee Thomason (grinliz)46a14cf2012-02-23 22:27:28 -0800733
734
735 {
736 // bug 1827248 Error while parsing a little bit malformed file
737 // Actually not malformed - should work.
738 XMLDocument xml;
739 xml.Parse( "<attributelist> </attributelist >" );
740 XMLTest( "Handle end tag whitespace", false, xml.Error() );
741 }
742
743 {
744 // This one must not result in an infinite loop
745 XMLDocument xml;
746 xml.Parse( "<infinite>loop" );
747 XMLTest( "Infinite loop test.", true, true );
748 }
749#endif
Lee Thomason7d00b9a2012-02-27 17:54:22 -0800750 {
751 const char* pub = "<?xml version='1.0'?> <element><sub/></element> <!--comment--> <!DOCTYPE>";
752 XMLDocument doc;
753 doc.Parse( pub );
754
755 XMLDocument clone;
756 for( const XMLNode* node=doc.FirstChild(); node; node=node->NextSibling() ) {
757 XMLNode* copy = node->ShallowClone( &clone );
758 clone.InsertEndChild( copy );
759 }
760
761 clone.Print();
762
763 int count=0;
764 const XMLNode* a=clone.FirstChild();
765 const XMLNode* b=doc.FirstChild();
766 for( ; a && b; a=a->NextSibling(), b=b->NextSibling() ) {
767 ++count;
768 XMLTest( "Clone and Equal", true, a->ShallowEqual( b ));
769 }
770 XMLTest( "Clone and Equal", 4, count );
771 }
Lee Thomason (grinliz)2a1cd272012-02-24 17:37:53 -0800772
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700773 {
774 // This shouldn't crash.
775 XMLDocument doc;
776 if(XML_NO_ERROR != doc.LoadFile( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ))
777 {
778 doc.PrintError();
779 }
780 XMLTest( "Error in snprinf handling.", true, doc.Error() );
781 }
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700782
Lee Thomason5e3803c2012-04-16 08:57:05 -0700783 {
784 // Attribute ordering.
785 static const char* xml = "<element attrib1=\"1\" attrib2=\"2\" attrib3=\"3\" />";
786 XMLDocument doc;
787 doc.Parse( xml );
788 XMLElement* ele = doc.FirstChildElement();
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700789
Lee Thomason5e3803c2012-04-16 08:57:05 -0700790 const XMLAttribute* a = ele->FirstAttribute();
791 XMLTest( "Attribute order", "1", a->Value() );
792 a = a->Next();
793 XMLTest( "Attribute order", "2", a->Value() );
794 a = a->Next();
795 XMLTest( "Attribute order", "3", a->Value() );
796 XMLTest( "Attribute order", "attrib3", a->Name() );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700797
Lee Thomason5e3803c2012-04-16 08:57:05 -0700798 ele->DeleteAttribute( "attrib2" );
799 a = ele->FirstAttribute();
800 XMLTest( "Attribute order", "1", a->Value() );
801 a = a->Next();
802 XMLTest( "Attribute order", "3", a->Value() );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700803
Lee Thomason5e3803c2012-04-16 08:57:05 -0700804 ele->DeleteAttribute( "attrib1" );
805 ele->DeleteAttribute( "attrib3" );
806 XMLTest( "Attribute order (empty)", false, ele->FirstAttribute() ? true : false );
807 }
Lee Thomason (grinliz)a4a36ba2012-04-06 21:24:29 -0700808
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700809 {
810 // Make sure an attribute with a space in it succeeds.
Lee Thomason78a773d2012-07-02 10:10:19 -0700811 static const char* xml0 = "<element attribute1= \"Test Attribute\"/>";
812 static const char* xml1 = "<element attribute1 =\"Test Attribute\"/>";
813 static const char* xml2 = "<element attribute1 = \"Test Attribute\"/>";
814 XMLDocument doc0;
815 doc0.Parse( xml0 );
816 XMLDocument doc1;
817 doc1.Parse( xml1 );
818 XMLDocument doc2;
819 doc2.Parse( xml2 );
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700820
Lee Thomason78a773d2012-07-02 10:10:19 -0700821 XMLElement* ele = 0;
822 ele = doc0.FirstChildElement();
823 XMLTest( "Attribute with space #1", "Test Attribute", ele->Attribute( "attribute1" ) );
824 ele = doc1.FirstChildElement();
825 XMLTest( "Attribute with space #2", "Test Attribute", ele->Attribute( "attribute1" ) );
826 ele = doc2.FirstChildElement();
827 XMLTest( "Attribute with space #3", "Test Attribute", ele->Attribute( "attribute1" ) );
Lee Thomason (grinliz)390e9782012-07-01 21:22:53 -0700828 }
829
830 {
831 // Make sure we don't go into an infinite loop.
832 static const char* xml = "<doc><element attribute='attribute'/><element attribute='attribute'/></doc>";
833 XMLDocument doc;
834 doc.Parse( xml );
835 XMLElement* ele0 = doc.FirstChildElement()->FirstChildElement();
836 XMLElement* ele1 = ele0->NextSiblingElement();
837 bool equal = ele0->ShallowEqual( ele1 );
838
839 XMLTest( "Infinite loop in shallow equal.", true, equal );
840 }
841
Lee Thomason5708f812012-03-28 17:46:41 -0700842 // -------- Handles ------------
843 {
844 static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
845 XMLDocument doc;
846 doc.Parse( xml );
Lee Thomason5708f812012-03-28 17:46:41 -0700847
848 XMLElement* ele = XMLHandle( doc ).FirstChildElement( "element" ).FirstChild().ToElement();
849 XMLTest( "Handle, success, mutable", ele->Value(), "sub" );
850
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700851 XMLHandle docH( doc );
852 ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
Lee Thomasond0b19df2012-04-12 08:41:37 -0700853 XMLTest( "Handle, dne, mutable", false, ele != 0 );
Lee Thomason5708f812012-03-28 17:46:41 -0700854 }
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700855
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700856 {
857 static const char* xml = "<element attrib='bar'><sub>Text</sub></element>";
858 XMLDocument doc;
859 doc.Parse( xml );
860 XMLConstHandle docH( doc );
861
862 const XMLElement* ele = docH.FirstChildElement( "element" ).FirstChild().ToElement();
863 XMLTest( "Handle, success, const", ele->Value(), "sub" );
864
865 ele = docH.FirstChildElement( "none" ).FirstChildElement( "element" ).ToElement();
Lee Thomasond0b19df2012-04-12 08:41:37 -0700866 XMLTest( "Handle, dne, const", false, ele != 0 );
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700867 }
Lee Thomasonf68c4382012-04-28 14:37:11 -0700868 {
869 // Default Declaration & BOM
870 XMLDocument doc;
871 doc.InsertEndChild( doc.NewDeclaration() );
872 doc.SetBOM( true );
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700873
Lee Thomasonf68c4382012-04-28 14:37:11 -0700874 XMLPrinter printer;
875 doc.Print( &printer );
876
877 static const char* result = "\xef\xbb\xbf<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
878 XMLTest( "BOM and default declaration", printer.CStr(), result, false );
Lee Thomason (grinliz)48ea0bc2012-05-26 14:41:14 -0700879 XMLTest( "CStrSize", printer.CStrSize(), 42, false );
Lee Thomasonf68c4382012-04-28 14:37:11 -0700880 }
Lee Thomason21be8822012-07-15 17:27:22 -0700881 {
882 const char* xml = "<ipxml ws='1'><info bla=' /></ipxml>";
883 XMLDocument doc;
884 doc.Parse( xml );
885 XMLTest( "Ill formed XML", true, doc.Error() );
886 }
887
888 // QueryXYZText
889 {
890 const char* xml = "<point> <x>1.2</x> <y>1</y> <z>38</z> <valid>true</valid> </point>";
891 XMLDocument doc;
892 doc.Parse( xml );
893
894 const XMLElement* pointElement = doc.RootElement();
895
896 int intValue = 0;
897 unsigned unsignedValue = 0;
898 float floatValue = 0;
899 double doubleValue = 0;
900 bool boolValue = false;
901
902 pointElement->FirstChildElement( "y" )->QueryIntText( &intValue );
903 pointElement->FirstChildElement( "y" )->QueryUnsignedText( &unsignedValue );
904 pointElement->FirstChildElement( "x" )->QueryFloatText( &floatValue );
905 pointElement->FirstChildElement( "x" )->QueryDoubleText( &doubleValue );
906 pointElement->FirstChildElement( "valid" )->QueryBoolText( &boolValue );
907
908
909 XMLTest( "QueryIntText", intValue, 1, false );
910 XMLTest( "QueryUnsignedText", unsignedValue, (unsigned)1, false );
911 XMLTest( "QueryFloatText", floatValue, 1.2f, false );
912 XMLTest( "QueryDoubleText", doubleValue, 1.2, false );
913 XMLTest( "QueryBoolText", boolValue, true, false );
914 }
Lee Thomason (grinliz)ae209f62012-04-04 22:00:07 -0700915
Lee Thomason (grinliz)5fbacbe2012-09-08 21:40:53 -0700916 {
917 const char* xml = "<element><_sub/><:sub/><sub:sub/><sub-sub/></element>";
918 XMLDocument doc;
919 doc.Parse( xml );
920 XMLTest( "Non-alpha element lead letter parses.", doc.Error(), false );
921 }
Lee Thomason (grinliz)62d1c5a2012-09-08 21:44:12 -0700922
Lee Thomason (grinliz)e2bcb322012-09-17 17:58:25 -0700923 {
924 const char* xml = "<element/>WOA THIS ISN'T GOING TO PARSE";
925 XMLDocument doc;
926 doc.Parse( xml, 10 );
Lee Thomason (grinliz)e2bcb322012-09-17 17:58:25 -0700927 XMLTest( "Set length of incoming data", doc.Error(), false );
928 }
929
Lee Thomason (grinliz)bc1bfb72012-08-20 22:00:38 -0700930 // ----------- Whitespace ------------
931 {
932 const char* xml = "<element>"
933 "<a> This \nis &apos; text &apos; </a>"
934 "<b> This is &apos; text &apos; \n</b>"
935 "<c>This is &apos; \n\n text &apos;</c>"
936 "</element>";
937 XMLDocument doc( true, COLLAPSE_WHITESPACE );
938 doc.Parse( xml );
939
940 const XMLElement* element = doc.FirstChildElement();
941 for( const XMLElement* parent = element->FirstChildElement();
942 parent;
943 parent = parent->NextSiblingElement() )
944 {
945 XMLTest( "Whitespace collapse", "This is ' text '", parent->GetText() );
946 }
947 }
Lee Thomason (grinliz)0fa82992012-09-08 21:53:47 -0700948
Lee Thomasonae9ab072012-10-24 10:17:53 -0700949#if 0
950 {
951 // Passes if assert doesn't fire.
952 XMLDocument xmlDoc;
953
954 xmlDoc.NewDeclaration();
955 xmlDoc.NewComment("Configuration file");
956
957 XMLElement *root = xmlDoc.NewElement("settings");
958 root->SetAttribute("version", 2);
959 }
960#endif
961
Lee Thomason (grinliz)0fa82992012-09-08 21:53:47 -0700962 {
963 const char* xml = "<element> </element>";
964 XMLDocument doc( true, COLLAPSE_WHITESPACE );
965 doc.Parse( xml );
966 XMLTest( "Whitespace all space", true, 0 == doc.FirstChildElement()->FirstChild() );
967 }
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -0700968
Lee Thomason (grinliz)fc6320e2012-09-23 20:25:50 -0700969#if 0 // the question being explored is what kind of print to use:
970 // https://github.com/leethomason/tinyxml2/issues/63
971 {
972 const char* xml = "<element attrA='123456789.123456789' attrB='1.001e9'/>";
973 XMLDocument doc;
974 doc.Parse( xml );
975 doc.FirstChildElement()->SetAttribute( "attrA", 123456789.123456789 );
976 doc.FirstChildElement()->SetAttribute( "attrB", 1.001e9 );
977 doc.Print();
978 }
979#endif
980
Lee Thomason5b0a6772012-11-19 13:54:42 -0800981 {
982 // An assert should not fire.
983 const char* xml = "<element/>";
984 XMLDocument doc;
985 doc.Parse( xml );
986 XMLElement* ele = doc.NewElement( "unused" ); // This will get cleaned up with the 'doc' going out of scope.
987 XMLTest( "Tracking unused elements", true, ele != 0, false );
988 }
989
Lee Thomason6f381b72012-03-02 12:59:39 -0800990 // ----------- Performance tracking --------------
991 {
992#if defined( _MSC_VER )
993 __int64 start, end, freq;
994 QueryPerformanceFrequency( (LARGE_INTEGER*) &freq );
995#endif
996
Bruno Diasa2d4e6e2012-05-07 04:58:11 -0300997 FILE* fp = fopen( "resources/dream.xml", "r" );
Lee Thomason6f381b72012-03-02 12:59:39 -0800998 fseek( fp, 0, SEEK_END );
999 long size = ftell( fp );
1000 fseek( fp, 0, SEEK_SET );
1001
1002 char* mem = new char[size+1];
1003 fread( mem, size, 1, fp );
1004 fclose( fp );
1005 mem[size] = 0;
1006
1007#if defined( _MSC_VER )
1008 QueryPerformanceCounter( (LARGE_INTEGER*) &start );
1009#else
1010 clock_t cstart = clock();
1011#endif
1012 static const int COUNT = 10;
1013 for( int i=0; i<COUNT; ++i ) {
1014 XMLDocument doc;
1015 doc.Parse( mem );
1016 }
1017#if defined( _MSC_VER )
1018 QueryPerformanceCounter( (LARGE_INTEGER*) &end );
1019#else
1020 clock_t cend = clock();
1021#endif
1022
1023 delete [] mem;
1024
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -07001025 static const char* note =
Lee Thomason6f381b72012-03-02 12:59:39 -08001026#ifdef DEBUG
1027 "DEBUG";
1028#else
1029 "Release";
1030#endif
1031
1032#if defined( _MSC_VER )
1033 printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, 1000.0 * (double)(end-start) / ( (double)freq * (double)COUNT) );
1034#else
1035 printf( "\nParsing %s of dream.xml: %.3f milli-seconds\n", note, (double)(cend - cstart)/(double)COUNT );
1036#endif
1037 }
1038
Lee Thomason (grinliz)7ca55582012-03-07 21:54:57 -08001039 #if defined( _MSC_VER ) && defined( DEBUG )
Lee Thomason (grinliz)2f1f6242012-09-16 11:32:34 -07001040 _CrtMemCheckpoint( &endMemState );
Lee Thomason1ff38e02012-02-14 18:18:16 -08001041 //_CrtMemDumpStatistics( &endMemState );
1042
1043 _CrtMemState diffMemState;
1044 _CrtMemDifference( &diffMemState, &startMemState, &endMemState );
1045 _CrtMemDumpStatistics( &diffMemState );
Lee Thomason (grinliz)bd0a8ac2012-02-20 20:14:33 -08001046 //printf( "new total=%d\n", gNewTotal );
Lee Thomason1ff38e02012-02-14 18:18:16 -08001047 #endif
1048
1049 printf ("\nPass %d, Fail %d\n", gPass, gFail);
U-Lama\Leee13c3e62011-12-28 14:36:55 -08001050 return 0;
Lee Thomason (grinliz)9b093cc2012-02-25 21:30:18 -08001051}