xmltest.cpp
上传用户:dlhongjiu
上传日期:2013-06-14
资源大小:1516k
文件大小:32k
源码类别:

信息检索与抽取

开发平台:

MultiPlatform

  1. /*
  2.    Test program for TinyXML.
  3. */
  4. #include "tinyxml.h"
  5. #ifdef TIXML_USE_STL
  6. #include <iostream>
  7. #include <sstream>
  8. using namespace std;
  9. #else
  10. #include <stdio.h>
  11. #endif
  12. #if defined( WIN32 ) && defined( TUNE )
  13. #include <windows.h>
  14. // Apologies to non-windows users! But I need some good timers for
  15. // profiling, and these are very platform specific.
  16. __int64 start;
  17. __int64 end;
  18. __int64 freq;
  19. #endif
  20. static int gPass = 0;
  21. static int gFail = 0;
  22. bool XmlTest (const char* testString, const char* expected, const char* found, bool noEcho = false)
  23. {
  24. bool pass = !strcmp( expected, found );
  25. if ( pass )
  26. printf ("[pass]");
  27. else
  28. printf ("[fail]");
  29. if ( noEcho )
  30. printf (" %sn", testString);
  31. else
  32. printf (" %s [%s][%s]n", testString, expected, found);
  33. if ( pass )
  34. ++gPass;
  35. else
  36. ++gFail;
  37. return pass;
  38. }
  39. bool XmlTest( const char* testString, int expected, int found, bool noEcho = false )
  40. {
  41. bool pass = ( expected == found );
  42. if ( pass )
  43. printf ("[pass]");
  44. else
  45. printf ("[fail]");
  46. if ( noEcho )
  47. printf (" %sn", testString);
  48. else
  49. printf (" %s [%d][%d]n", testString, expected, found);
  50. if ( pass )
  51. ++gPass;
  52. else
  53. ++gFail;
  54. return pass;
  55. }
  56. //
  57. // This file demonstrates some basic functionality of TinyXml.
  58. // Note that the example is very contrived. It presumes you know
  59. // what is in the XML file. But it does test the basic operations,
  60. // and show how to add and remove nodes.
  61. //
  62. int main()
  63. {
  64. //
  65. // We start with the 'demoStart' todo list. Process it. And
  66. // should hopefully end up with the todo list as illustrated.
  67. //
  68. const char* demoStart =
  69. "<?xml version="1.0"  standalone='no' >n"
  70. "<!-- Our to do list data -->"
  71. "<ToDo>n"
  72. "<!-- Do I need a secure PDA? -->n"
  73. "<Item priority="1" distance='close'> Go to the <bold>Toy store!</bold></Item>"
  74. "<Item priority="2" distance='none'> Do bills   </Item>"
  75. "<Item priority="2" distance='far &amp; back'> Look for Evil Dinosaurs! </Item>"
  76. "</ToDo>";
  77. #ifdef TIXML_USE_STL
  78. /* What the todo list should look like after processing.
  79. In stream (no formatting) representation. */
  80. const char* demoEnd =
  81. "<?xml version="1.0" standalone="no" ?>"
  82. "<!-- Our to do list data -->"
  83. "<ToDo>"
  84. "<!-- Do I need a secure PDA? -->"
  85. "<Item priority="2" distance="close">Go to the"
  86. "<bold>Toy store!"
  87. "</bold>"
  88. "</Item>"
  89. "<Item priority="1" distance="far">Talk to:"
  90. "<Meeting where="School">"
  91. "<Attendee name="Marple" position="teacher" />"
  92. "<Attendee name="Voel" position="counselor" />"
  93. "</Meeting>"
  94. "<Meeting where="Lunch" />"
  95. "</Item>"
  96. "<Item priority="2" distance="here">Do bills"
  97. "</Item>"
  98. "</ToDo>";
  99. #endif
  100. // The example parses from the character string (above):
  101. #if defined( WIN32 ) && defined( TUNE )
  102. QueryPerformanceCounter( (LARGE_INTEGER*) (&start) );
  103. #endif
  104. {
  105. // Write to a file and read it back, to check file I/O.
  106. TiXmlDocument doc( "demotest.xml" );
  107. doc.Parse( demoStart );
  108. if ( doc.Error() )
  109. {
  110. printf( "Error in %s: %sn", doc.Value(), doc.ErrorDesc() );
  111. exit( 1 );
  112. }
  113. doc.SaveFile();
  114. }
  115. TiXmlDocument doc( "demotest.xml" );
  116. bool loadOkay = doc.LoadFile();
  117. if ( !loadOkay )
  118. {
  119. printf( "Could not load test file 'demotest.xml'. Error='%s'. Exiting.n", doc.ErrorDesc() );
  120. exit( 1 );
  121. }
  122. printf( "** Demo doc read from disk: ** nn" );
  123. doc.Print( stdout );
  124. TiXmlNode* node = 0;
  125. TiXmlElement* todoElement = 0;
  126. TiXmlElement* itemElement = 0;
  127. // --------------------------------------------------------
  128. // An example of changing existing attributes, and removing
  129. // an element from the document.
  130. // --------------------------------------------------------
  131. // Get the "ToDo" element.
  132. // It is a child of the document, and can be selected by name.
  133. node = doc.FirstChild( "ToDo" );
  134. assert( node );
  135. todoElement = node->ToElement();
  136. assert( todoElement  );
  137. // Going to the toy store is now our second priority...
  138. // So set the "priority" attribute of the first item in the list.
  139. node = todoElement->FirstChildElement(); // This skips the "PDA" comment.
  140. assert( node );
  141. itemElement = node->ToElement();
  142. assert( itemElement  );
  143. itemElement->SetAttribute( "priority", 2 );
  144. // Change the distance to "doing bills" from
  145. // "none" to "here". It's the next sibling element.
  146. itemElement = itemElement->NextSiblingElement();
  147. assert( itemElement );
  148. itemElement->SetAttribute( "distance", "here" );
  149. // Remove the "Look for Evil Dinosaurs!" item.
  150. // It is 1 more sibling away. We ask the parent to remove
  151. // a particular child.
  152. itemElement = itemElement->NextSiblingElement();
  153. todoElement->RemoveChild( itemElement );
  154. itemElement = 0;
  155. // --------------------------------------------------------
  156. // What follows is an example of created elements and text
  157. // nodes and adding them to the document.
  158. // --------------------------------------------------------
  159. // Add some meetings.
  160. TiXmlElement item( "Item" );
  161. item.SetAttribute( "priority", "1" );
  162. item.SetAttribute( "distance", "far" );
  163. TiXmlText text( "Talk to:" );
  164. TiXmlElement meeting1( "Meeting" );
  165. meeting1.SetAttribute( "where", "School" );
  166. TiXmlElement meeting2( "Meeting" );
  167. meeting2.SetAttribute( "where", "Lunch" );
  168. TiXmlElement attendee1( "Attendee" );
  169. attendee1.SetAttribute( "name", "Marple" );
  170. attendee1.SetAttribute( "position", "teacher" );
  171. TiXmlElement attendee2( "Attendee" );
  172. attendee2.SetAttribute( "name", "Voel" );
  173. attendee2.SetAttribute( "position", "counselor" );
  174. // Assemble the nodes we've created:
  175. meeting1.InsertEndChild( attendee1 );
  176. meeting1.InsertEndChild( attendee2 );
  177. item.InsertEndChild( text );
  178. item.InsertEndChild( meeting1 );
  179. item.InsertEndChild( meeting2 );
  180. // And add the node to the existing list after the first child.
  181. node = todoElement->FirstChild( "Item" );
  182. assert( node );
  183. itemElement = node->ToElement();
  184. assert( itemElement );
  185. todoElement->InsertAfterChild( itemElement, item );
  186. printf( "n** Demo doc processed: ** nn" );
  187. doc.Print( stdout );
  188. #ifdef TIXML_USE_STL
  189. printf( "** Demo doc processed to stream: ** nn" );
  190. cout << doc << endl << endl;
  191. #endif
  192. // --------------------------------------------------------
  193. // Different tests...do we have what we expect?
  194. // --------------------------------------------------------
  195. int count = 0;
  196. TiXmlElement* element;
  197. //////////////////////////////////////////////////////
  198. #ifdef TIXML_USE_STL
  199. cout << "** Basic structure. **n";
  200. ostringstream outputStream( ostringstream::out );
  201. outputStream << doc;
  202. XmlTest( "Output stream correct.", string( demoEnd ).c_str(),
  203. outputStream.str().c_str(), true );
  204. #endif
  205. node = doc.RootElement();
  206. XmlTest( "Root element exists.", true, ( node != 0 && node->ToElement() ) );
  207. XmlTest ( "Root element value is 'ToDo'.", "ToDo",  node->Value());
  208. node = node->FirstChild();
  209. XmlTest( "First child exists & is a comment.", true, ( node != 0 && node->ToComment() ) );
  210. node = node->NextSibling();
  211. XmlTest( "Sibling element exists & is an element.", true, ( node != 0 && node->ToElement() ) );
  212. XmlTest ( "Value is 'Item'.", "Item", node->Value() );
  213. node = node->FirstChild();
  214. XmlTest ( "First child exists.", true, ( node != 0 && node->ToText() ) );
  215. XmlTest ( "Value is 'Go to the'.", "Go to the", node->Value() );
  216. //////////////////////////////////////////////////////
  217. printf ("n** Iterators. **n");
  218. // Walk all the top level nodes of the document.
  219. count = 0;
  220. for( node = doc.FirstChild();
  221.  node;
  222.  node = node->NextSibling() )
  223. {
  224. count++;
  225. }
  226. XmlTest( "Top level nodes, using First / Next.", 3, count );
  227. count = 0;
  228. for( node = doc.LastChild();
  229.  node;
  230.  node = node->PreviousSibling() )
  231. {
  232. count++;
  233. }
  234. XmlTest( "Top level nodes, using Last / Previous.", 3, count );
  235. // Walk all the top level nodes of the document,
  236. // using a different syntax.
  237. count = 0;
  238. for( node = doc.IterateChildren( 0 );
  239.  node;
  240.  node = doc.IterateChildren( node ) )
  241. {
  242. count++;
  243. }
  244. XmlTest( "Top level nodes, using IterateChildren.", 3, count );
  245. // Walk all the elements in a node.
  246. count = 0;
  247. for( element = todoElement->FirstChildElement();
  248.  element;
  249.  element = element->NextSiblingElement() )
  250. {
  251. count++;
  252. }
  253. XmlTest( "Children of the 'ToDo' element, using First / Next.",
  254. 3, count );
  255. // Walk all the elements in a node by value.
  256. count = 0;
  257. for( node = todoElement->FirstChild( "Item" );
  258.  node;
  259.  node = node->NextSibling( "Item" ) )
  260. {
  261. count++;
  262. }
  263. XmlTest( "'Item' children of the 'ToDo' element, using First/Next.", 3, count );
  264. count = 0;
  265. for( node = todoElement->LastChild( "Item" );
  266.  node;
  267.  node = node->PreviousSibling( "Item" ) )
  268. {
  269. count++;
  270. }
  271. XmlTest( "'Item' children of the 'ToDo' element, using Last/Previous.", 3, count );
  272. #ifdef TIXML_USE_STL
  273. {
  274. cout << "n** Parsing. **n";
  275. istringstream parse0( "<Element0 attribute0='foo0' attribute1= noquotes attribute2 = '&gt;' />" );
  276. TiXmlElement element0( "default" );
  277. parse0 >> element0;
  278. XmlTest ( "Element parsed, value is 'Element0'.", "Element0", element0.Value() );
  279. XmlTest ( "Reads attribute 'attribute0="foo0"'.", "foo0", element0.Attribute( "attribute0" ));
  280. XmlTest ( "Reads incorrectly formatted 'attribute1=noquotes'.", "noquotes", element0.Attribute( "attribute1" ) );
  281. XmlTest ( "Read attribute with entity value '>'.", ">", element0.Attribute( "attribute2" ) );
  282. }
  283. #endif
  284. {
  285. const char* error = "<?xml version="1.0" standalone="no" ?>n"
  286. "<passages count="006" formatversion="20020620">n"
  287. "    <wrong error>n"
  288. "</passages>";
  289.         TiXmlDocument doc;
  290. doc.Parse( error );
  291. XmlTest( "Error row", doc.ErrorRow(), 3 );
  292. XmlTest( "Error column", doc.ErrorCol(), 17 );
  293. //printf( "error=%d id='%s' row %d col%dn", (int) doc.Error(), doc.ErrorDesc(), doc.ErrorRow()+1, doc.ErrorCol() + 1 );
  294. }
  295. {
  296. const char* str = "t<?xml version="1.0" standalone="no" ?>t<room doors='2'>n"
  297. "  <!-- Silly example -->n"
  298. "    <door wall='north'>A great door!</door>n"
  299. "t<door wall='east'/>"
  300. "</room>";
  301.         TiXmlDocument doc;
  302. doc.Parse( str );
  303. TiXmlHandle docHandle( &doc );
  304. TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
  305. TiXmlHandle commentHandle = docHandle.FirstChildElement( "room" ).FirstChild();
  306. TiXmlHandle textHandle = docHandle.FirstChildElement( "room" ).ChildElement( "door", 0 ).FirstChild();
  307. TiXmlHandle door0Handle = docHandle.FirstChildElement( "room" ).ChildElement( 0 );
  308. TiXmlHandle door1Handle = docHandle.FirstChildElement( "room" ).ChildElement( 1 );
  309. assert( docHandle.Node() );
  310. assert( roomHandle.Element() );
  311. assert( commentHandle.Node() );
  312. assert( textHandle.Text() );
  313. assert( door0Handle.Element() );
  314. assert( door1Handle.Element() );
  315. TiXmlDeclaration* declaration = doc.FirstChild()->ToDeclaration();
  316. assert( declaration );
  317. TiXmlElement* room = roomHandle.Element();
  318. assert( room );
  319. TiXmlAttribute* doors = room->FirstAttribute();
  320. assert( doors );
  321. TiXmlText* text = textHandle.Text();
  322. TiXmlComment* comment = commentHandle.Node()->ToComment();
  323. assert( comment );
  324. TiXmlElement* door0 = door0Handle.Element();
  325. TiXmlElement* door1 = door1Handle.Element();
  326. XmlTest( "Location tracking: Declaration row", declaration->Row(), 1 );
  327. XmlTest( "Location tracking: Declaration col", declaration->Column(), 5 );
  328. XmlTest( "Location tracking: room row", room->Row(), 1 );
  329. XmlTest( "Location tracking: room col", room->Column(), 45 );
  330. XmlTest( "Location tracking: doors row", doors->Row(), 1 );
  331. XmlTest( "Location tracking: doors col", doors->Column(), 51 );
  332. XmlTest( "Location tracking: Comment row", comment->Row(), 2 );
  333. XmlTest( "Location tracking: Comment col", comment->Column(), 3 );
  334. XmlTest( "Location tracking: text row", text->Row(), 3 ); 
  335. XmlTest( "Location tracking: text col", text->Column(), 24 );
  336. XmlTest( "Location tracking: door0 row", door0->Row(), 3 );
  337. XmlTest( "Location tracking: door0 col", door0->Column(), 5 );
  338. XmlTest( "Location tracking: door1 row", door1->Row(), 4 );
  339. XmlTest( "Location tracking: door1 col", door1->Column(), 5 );
  340. }
  341. {
  342. const char* str = "t<?xml version="1.0" standalone="no" ?>t<room doors='2'>n"
  343. "</room>";
  344.         TiXmlDocument doc;
  345. doc.SetTabSize( 8 );
  346. doc.Parse( str );
  347. TiXmlHandle docHandle( &doc );
  348. TiXmlHandle roomHandle = docHandle.FirstChildElement( "room" );
  349. assert( docHandle.Node() );
  350. assert( roomHandle.Element() );
  351. TiXmlElement* room = roomHandle.Element();
  352. assert( room );
  353. TiXmlAttribute* doors = room->FirstAttribute();
  354. assert( doors );
  355. XmlTest( "Location tracking: Tab 8: room row", room->Row(), 1 );
  356. XmlTest( "Location tracking: Tab 8: room col", room->Column(), 49 );
  357. XmlTest( "Location tracking: Tab 8: doors row", doors->Row(), 1 );
  358. XmlTest( "Location tracking: Tab 8: doors col", doors->Column(), 55 );
  359. }
  360. {
  361. const char* str = "<doc attr0='1' attr1='2.0' attr2='foo' />";
  362. TiXmlDocument doc;
  363. doc.Parse( str );
  364. TiXmlElement* ele = doc.FirstChildElement();
  365. int iVal, result;
  366. double dVal;
  367. result = ele->QueryDoubleAttribute( "attr0", &dVal );
  368. XmlTest( "Query attribute: int as double", result, TIXML_SUCCESS );
  369. XmlTest( "Query attribute: int as double", (int)dVal, 1 );
  370. result = ele->QueryDoubleAttribute( "attr1", &dVal );
  371. XmlTest( "Query attribute: double as double", (int)dVal, 2 );
  372. result = ele->QueryIntAttribute( "attr1", &iVal );
  373. XmlTest( "Query attribute: double as int", result, TIXML_SUCCESS );
  374. XmlTest( "Query attribute: double as int", iVal, 2 );
  375. result = ele->QueryIntAttribute( "attr2", &iVal );
  376. XmlTest( "Query attribute: not a number", result, TIXML_WRONG_TYPE );
  377. result = ele->QueryIntAttribute( "bar", &iVal );
  378. XmlTest( "Query attribute: does not exist", result, TIXML_NO_ATTRIBUTE );
  379. }
  380. #ifdef TIXML_USE_STL
  381. {
  382. //////////////////////////////////////////////////////
  383. cout << "n** Streaming. **n";
  384. // Round trip check: stream in, then stream back out to verify. The stream
  385. // out has already been checked, above. We use the output
  386. istringstream inputStringStream( outputStream.str() );
  387. TiXmlDocument document0;
  388. inputStringStream >> document0;
  389. ostringstream outputStream0( ostringstream::out );
  390. outputStream0 << document0;
  391. XmlTest( "Stream round trip correct.", string( demoEnd ).c_str(), 
  392. outputStream0.str().c_str(), true );
  393. std::string str;
  394. str << document0;
  395. XmlTest( "String printing correct.", string( demoEnd ).c_str(), 
  396.  str.c_str(), true );
  397. }
  398. #endif
  399. // --------------------------------------------------------
  400. // UTF-8 testing. It is important to test:
  401. // 1. Making sure name, value, and text read correctly
  402. // 2. Row, Col functionality
  403. // 3. Correct output
  404. // --------------------------------------------------------
  405. printf ("n** UTF-8 **n");
  406. {
  407. TiXmlDocument doc( "utf8test.xml" );
  408. doc.LoadFile();
  409. if ( doc.Error() && doc.ErrorId() == TiXmlBase::TIXML_ERROR_OPENING_FILE ) {
  410. printf( "WARNING: File 'utf8test.xml' not found.n"
  411. "(Are you running the test from the wrong directory?)n"
  412.     "Could not test UTF-8 functionality.n" );
  413. }
  414. else
  415. {
  416. TiXmlHandle docH( &doc );
  417. // Get the attribute "value" from the "Russian" element and check it.
  418. TiXmlElement* element = docH.FirstChildElement( "document" ).FirstChildElement( "Russian" ).Element();
  419. const unsigned char correctValue[] = { 0xd1U, 0x86U, 0xd0U, 0xb5U, 0xd0U, 0xbdU, 0xd0U, 0xbdU, 
  420. 0xd0U, 0xbeU, 0xd1U, 0x81U, 0xd1U, 0x82U, 0xd1U, 0x8cU, 0 };
  421. XmlTest( "UTF-8: Russian value.", (const char*)correctValue, element->Attribute( "value" ), true );
  422. XmlTest( "UTF-8: Russian value row.", 4, element->Row() );
  423. XmlTest( "UTF-8: Russian value column.", 5, element->Column() );
  424. const unsigned char russianElementName[] = { 0xd0U, 0xa0U, 0xd1U, 0x83U,
  425. 0xd1U, 0x81U, 0xd1U, 0x81U,
  426. 0xd0U, 0xbaU, 0xd0U, 0xb8U,
  427. 0xd0U, 0xb9U, 0 };
  428. const char russianText[] = "<xD0xB8xD0xBCxD0xB5xD0xB5xD1x82>";
  429. TiXmlText* text = docH.FirstChildElement( "document" ).FirstChildElement( (const char*) russianElementName ).Child( 0 ).Text();
  430. XmlTest( "UTF-8: Browsing russian element name.",
  431.  russianText,
  432.  text->Value(),
  433.  true );
  434. XmlTest( "UTF-8: Russian element name row.", 7, text->Row() );
  435. XmlTest( "UTF-8: Russian element name column.", 47, text->Column() );
  436. TiXmlDeclaration* dec = docH.Child( 0 ).Node()->ToDeclaration();
  437. XmlTest( "UTF-8: Declaration column.", 1, dec->Column() );
  438. XmlTest( "UTF-8: Document column.", 1, doc.Column() );
  439. // Now try for a round trip.
  440. doc.SaveFile( "utf8testout.xml" );
  441. // Check the round trip.
  442. char savedBuf[256];
  443. char verifyBuf[256];
  444. int okay = 1;
  445. FILE* saved  = fopen( "utf8testout.xml", "r" );
  446. FILE* verify = fopen( "utf8testverify.xml", "r" );
  447. if ( saved && verify )
  448. {
  449. while ( fgets( verifyBuf, 256, verify ) )
  450. {
  451. fgets( savedBuf, 256, saved );
  452. if ( strcmp( verifyBuf, savedBuf ) )
  453. {
  454. okay = 0;
  455. break;
  456. }
  457. }
  458. fclose( saved );
  459. fclose( verify );
  460. }
  461. XmlTest( "UTF-8: Verified multi-language round trip.", 1, okay );
  462. // On most Western machines, this is an element that contains
  463. // the word "resume" with the correct accents, in a latin encoding.
  464. // It will be something else completely on non-wester machines,
  465. // which is why TinyXml is switching to UTF-8.
  466. const char latin[] = "<element>rx82sumx82</element>";
  467. TiXmlDocument latinDoc;
  468. latinDoc.Parse( latin, 0, TIXML_ENCODING_LEGACY );
  469. text = latinDoc.FirstChildElement()->FirstChild()->ToText();
  470. XmlTest( "Legacy encoding: Verify text element.", "rx82sumx82", text->Value() );
  471. }
  472. }
  473. //////////////////////
  474. // Copy and assignment
  475. //////////////////////
  476. printf ("n** Copy and Assignment **n");
  477. {
  478. TiXmlElement element( "foo" );
  479. element.Parse( "<element name='value' />", 0, TIXML_ENCODING_UNKNOWN );
  480. TiXmlElement elementCopy( element );
  481. TiXmlElement elementAssign( "foo" );
  482. elementAssign.Parse( "<incorrect foo='bar'/>", 0, TIXML_ENCODING_UNKNOWN );
  483. elementAssign = element;
  484. XmlTest( "Copy/Assign: element copy #1.", "element", elementCopy.Value() );
  485. XmlTest( "Copy/Assign: element copy #2.", "value", elementCopy.Attribute( "name" ) );
  486. XmlTest( "Copy/Assign: element assign #1.", "element", elementAssign.Value() );
  487. XmlTest( "Copy/Assign: element assign #2.", "value", elementAssign.Attribute( "name" ) );
  488. XmlTest( "Copy/Assign: element assign #3.", 0, (int) elementAssign.Attribute( "foo" ) );
  489. TiXmlComment comment;
  490. comment.Parse( "<!--comment-->", 0, TIXML_ENCODING_UNKNOWN );
  491. TiXmlComment commentCopy( comment );
  492. TiXmlComment commentAssign;
  493. commentAssign = commentCopy;
  494. XmlTest( "Copy/Assign: comment copy.", "comment", commentCopy.Value() );
  495. XmlTest( "Copy/Assign: comment assign.", "comment", commentAssign.Value() );
  496. TiXmlUnknown unknown;
  497. unknown.Parse( "<[unknown]>", 0, TIXML_ENCODING_UNKNOWN );
  498. TiXmlUnknown unknownCopy( unknown );
  499. TiXmlUnknown unknownAssign;
  500. unknownAssign.Parse( "incorrect", 0, TIXML_ENCODING_UNKNOWN );
  501. unknownAssign = unknownCopy;
  502. XmlTest( "Copy/Assign: unknown copy.", "[unknown]", unknownCopy.Value() );
  503. XmlTest( "Copy/Assign: unknown assign.", "[unknown]", unknownAssign.Value() );
  504. TiXmlText text( "TextNode" );
  505. TiXmlText textCopy( text );
  506. TiXmlText textAssign( "incorrect" );
  507. textAssign = text;
  508. XmlTest( "Copy/Assign: text copy.", "TextNode", textCopy.Value() );
  509. XmlTest( "Copy/Assign: text assign.", "TextNode", textAssign.Value() );
  510. TiXmlDeclaration dec;
  511. dec.Parse( "<?xml version='1.0' encoding='UTF-8'?>", 0, TIXML_ENCODING_UNKNOWN );
  512. TiXmlDeclaration decCopy( dec );
  513. TiXmlDeclaration decAssign;
  514. decAssign = dec;
  515. XmlTest( "Copy/Assign: declaration copy.", "UTF-8", decCopy.Encoding() );
  516. XmlTest( "Copy/Assign: text assign.", "UTF-8", decAssign.Encoding() );
  517. TiXmlDocument doc;
  518. elementCopy.InsertEndChild( textCopy );
  519. doc.InsertEndChild( decAssign );
  520. doc.InsertEndChild( elementCopy );
  521. doc.InsertEndChild( unknownAssign );
  522. TiXmlDocument docCopy( doc );
  523. TiXmlDocument docAssign;
  524. docAssign = docCopy;
  525. #ifdef TIXML_USE_STL
  526. std::string original, copy, assign;
  527. original << doc;
  528. copy << docCopy;
  529. assign << docAssign;
  530. XmlTest( "Copy/Assign: document copy.", original.c_str(), copy.c_str(), true );
  531. XmlTest( "Copy/Assign: document assign.", original.c_str(), assign.c_str(), true );
  532. #endif
  533. }
  534. //////////////////////////////////////////////////////
  535. #ifdef TIXML_USE_STL
  536. printf ("n** Parsing, no Condense Whitespace **n");
  537. TiXmlBase::SetCondenseWhiteSpace( false );
  538. istringstream parse1( "<start>This  is    ntext</start>" );
  539. TiXmlElement text1( "text" );
  540. parse1 >> text1;
  541. XmlTest ( "Condense white space OFF.", "This  is    ntext",
  542. text1.FirstChild()->Value(),
  543. true );
  544. TiXmlBase::SetCondenseWhiteSpace( true );
  545. #endif
  546. //////////////////////////////////////////////////////
  547. // GetText();
  548. {
  549. const char* str = "<foo>This is text</foo>";
  550. TiXmlDocument doc;
  551. doc.Parse( str );
  552. const TiXmlElement* element = doc.RootElement();
  553. XmlTest( "GetText() normal use.", "This is text", element->GetText() );
  554. str = "<foo><b>This is text</b></foo>";
  555. doc.Clear();
  556. doc.Parse( str );
  557. element = doc.RootElement();
  558. XmlTest( "GetText() contained element.", element->GetText() == 0, true );
  559. str = "<foo>This is <b>text</b></foo>";
  560. doc.Clear();
  561. TiXmlBase::SetCondenseWhiteSpace( false );
  562. doc.Parse( str );
  563. TiXmlBase::SetCondenseWhiteSpace( true );
  564. element = doc.RootElement();
  565. XmlTest( "GetText() partial.", "This is ", element->GetText() );
  566. }
  567. //////////////////////////////////////////////////////
  568. // CDATA
  569. {
  570. const char* str = "<xmlElement>"
  571. "<![CDATA["
  572. "I am > the rules!n"
  573. "...since I make symbolic puns"
  574. "]]>"
  575. "</xmlElement>";
  576. TiXmlDocument doc;
  577. doc.Parse( str );
  578. doc.Print();
  579. XmlTest( "CDATA parse.", doc.FirstChildElement()->FirstChild()->Value(), 
  580.  "I am > the rules!n...since I make symbolic puns",
  581.  true );
  582. #ifdef TIXML_USE_STL
  583. //cout << doc << 'n';
  584. doc.Clear();
  585. istringstream parse0( str );
  586. parse0 >> doc;
  587. //cout << doc << 'n';
  588. XmlTest( "CDATA stream.", doc.FirstChildElement()->FirstChild()->Value(), 
  589.  "I am > the rules!n...since I make symbolic puns",
  590.  true );
  591. #endif
  592. TiXmlDocument doc1 = doc;
  593. //doc.Print();
  594. XmlTest( "CDATA copy.", doc1.FirstChildElement()->FirstChild()->Value(), 
  595.  "I am > the rules!n...since I make symbolic puns",
  596.  true );
  597. }
  598. //////////////////////////////////////////////////////
  599. printf ("n** Bug regression tests **n");
  600. // InsertBeforeChild and InsertAfterChild causes crash.
  601. {
  602. TiXmlElement parent( "Parent" );
  603. TiXmlElement childText0( "childText0" );
  604. TiXmlElement childText1( "childText1" );
  605. TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
  606. TiXmlNode* childNode1 = parent.InsertBeforeChild( childNode0, childText1 );
  607. XmlTest( "Test InsertBeforeChild on empty node.", ( childNode1 == parent.FirstChild() ), true );
  608. }
  609. {
  610. // InsertBeforeChild and InsertAfterChild causes crash.
  611. TiXmlElement parent( "Parent" );
  612. TiXmlElement childText0( "childText0" );
  613. TiXmlElement childText1( "childText1" );
  614. TiXmlNode* childNode0 = parent.InsertEndChild( childText0 );
  615. TiXmlNode* childNode1 = parent.InsertAfterChild( childNode0, childText1 );
  616. XmlTest( "Test InsertAfterChild on empty node. ", ( childNode1 == parent.LastChild() ), true );
  617. }
  618. // Reports of missing constructors, irregular string problems.
  619. {
  620. // Missing constructor implementation. No test -- just compiles.
  621. TiXmlText text( "Missing" );
  622. #ifdef TIXML_USE_STL
  623. // Missing implementation:
  624. TiXmlDocument doc;
  625. string name = "missing";
  626. doc.LoadFile( name );
  627. TiXmlText textSTL( name );
  628. #else
  629. // verifying some basic string functions:
  630. TiXmlString a;
  631. TiXmlString b( "Hello" );
  632. TiXmlString c( "ooga" );
  633. c = " World!";
  634. a = b;
  635. a += c;
  636. a = a;
  637. XmlTest( "Basic TiXmlString test. ", "Hello World!", a.c_str() );
  638. #endif
  639.   }
  640. // Long filenames crashing STL version
  641. {
  642. TiXmlDocument doc( "midsummerNightsDreamWithAVeryLongFilenameToConfuseTheStringHandlingRoutines.xml" );
  643. bool loadOkay = doc.LoadFile();
  644. loadOkay = true; // get rid of compiler warning.
  645. // Won't pass on non-dev systems. Just a "no crash" check.
  646. //XmlTest( "Long filename. ", true, loadOkay );
  647. }
  648. {
  649. // Entities not being written correctly.
  650. // From Lynn Allen
  651. const char* passages =
  652. "<?xml version="1.0" standalone="no" ?>"
  653. "<passages count="006" formatversion="20020620">"
  654. "<psg context="Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
  655. " It also has &lt;, &gt;, and &amp;, as well as a fake copyright &#xA9;."> </psg>"
  656. "</passages>";
  657. TiXmlDocument doc( "passages.xml" );
  658. doc.Parse( passages );
  659. TiXmlElement* psg = doc.RootElement()->FirstChildElement();
  660. const char* context = psg->Attribute( "context" );
  661. const char* expected = "Line 5 has "quotation marks" and 'apostrophe marks'. It also has <, >, and &, as well as a fake copyright xC2xA9.";
  662. XmlTest( "Entity transformation: read. ", expected, context, true );
  663. FILE* textfile = fopen( "textfile.txt", "w" );
  664. if ( textfile )
  665. {
  666. psg->Print( textfile, 0 );
  667. fclose( textfile );
  668. }
  669. textfile = fopen( "textfile.txt", "r" );
  670. assert( textfile );
  671. if ( textfile )
  672. {
  673. char buf[ 1024 ];
  674. fgets( buf, 1024, textfile );
  675. XmlTest( "Entity transformation: write. ",
  676.  "<psg context='Line 5 has &quot;quotation marks&quot; and &apos;apostrophe marks&apos;."
  677.  " It also has &lt;, &gt;, and &amp;, as well as a fake copyright xC2xA9.' />",
  678.  buf,
  679.  true );
  680. }
  681. fclose( textfile );
  682. }
  683.     {
  684. FILE* textfile = fopen( "test5.xml", "w" );
  685. if ( textfile )
  686. {
  687.             fputs("<?xml version='1.0'?><a.elem xmi.version='2.0'/>", textfile);
  688.             fclose(textfile);
  689. TiXmlDocument doc;
  690.             doc.LoadFile( "test5.xml" );
  691.             XmlTest( "dot in element attributes and names", doc.Error(), 0);
  692. }
  693.     }
  694. {
  695. FILE* textfile = fopen( "test6.xml", "w" );
  696. if ( textfile )
  697. {
  698.             fputs("<element><Name>1.1 Start easy ignore fin thickness&#xA;</Name></element>", textfile );
  699.             fclose(textfile);
  700.             TiXmlDocument doc;
  701.             bool result = doc.LoadFile( "test6.xml" );
  702.             XmlTest( "Entity with one digit.", result, true );
  703. TiXmlText* text = doc.FirstChildElement()->FirstChildElement()->FirstChild()->ToText();
  704. XmlTest( "Entity with one digit.",
  705. text->Value(), "1.1 Start easy ignore fin thicknessn" );
  706. }
  707.     }
  708. {
  709. // DOCTYPE not preserved (950171)
  710. // 
  711. const char* doctype =
  712. "<?xml version="1.0" ?>"
  713. "<!DOCTYPE PLAY SYSTEM 'play.dtd'>"
  714. "<!ELEMENT title (#PCDATA)>"
  715. "<!ELEMENT books (title,authors)>"
  716. "<element />";
  717. TiXmlDocument doc;
  718. doc.Parse( doctype );
  719. doc.SaveFile( "test7.xml" );
  720. doc.Clear();
  721. doc.LoadFile( "test7.xml" );
  722. TiXmlHandle docH( &doc );
  723. TiXmlUnknown* unknown = docH.Child( 1 ).Unknown();
  724. XmlTest( "Correct value of unknown.", "!DOCTYPE PLAY SYSTEM 'play.dtd'", unknown->Value() );
  725. #ifdef TIXML_USE_STL
  726. TiXmlNode* node = docH.Child( 2 ).Node();
  727. std::string str;
  728. str << (*node);
  729. XmlTest( "Correct streaming of unknown.", "<!ELEMENT title (#PCDATA)>", str.c_str() );
  730. #endif
  731. }
  732. {
  733. // [ 791411 ] Formatting bug
  734. // Comments do not stream out correctly.
  735. const char* doctype = 
  736. "<!-- Somewhat<evil> -->";
  737. TiXmlDocument doc;
  738. doc.Parse( doctype );
  739. TiXmlHandle docH( &doc );
  740. TiXmlComment* comment = docH.Child( 0 ).Node()->ToComment();
  741. XmlTest( "Comment formatting.", " Somewhat<evil> ", comment->Value() );
  742. #ifdef TIXML_USE_STL
  743. std::string str;
  744. str << (*comment);
  745. XmlTest( "Comment streaming.", "<!-- Somewhat<evil> -->", str.c_str() );
  746. #endif
  747. }
  748. {
  749. // [ 870502 ] White space issues
  750. TiXmlDocument doc;
  751. TiXmlText* text;
  752. TiXmlHandle docH( &doc );
  753. const char* doctype0 = "<element> This has leading and trailing space </element>";
  754. const char* doctype1 = "<element>This has  internal space</element>";
  755. const char* doctype2 = "<element> This has leading, trailing, and  internal space </element>";
  756. TiXmlBase::SetCondenseWhiteSpace( false );
  757. doc.Clear();
  758. doc.Parse( doctype0 );
  759. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  760. XmlTest( "White space kept.", " This has leading and trailing space ", text->Value() );
  761. doc.Clear();
  762. doc.Parse( doctype1 );
  763. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  764. XmlTest( "White space kept.", "This has  internal space", text->Value() );
  765. doc.Clear();
  766. doc.Parse( doctype2 );
  767. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  768. XmlTest( "White space kept.", " This has leading, trailing, and  internal space ", text->Value() );
  769. TiXmlBase::SetCondenseWhiteSpace( true );
  770. doc.Clear();
  771. doc.Parse( doctype0 );
  772. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  773. XmlTest( "White space condensed.", "This has leading and trailing space", text->Value() );
  774. doc.Clear();
  775. doc.Parse( doctype1 );
  776. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  777. XmlTest( "White space condensed.", "This has internal space", text->Value() );
  778. doc.Clear();
  779. doc.Parse( doctype2 );
  780. text = docH.FirstChildElement( "element" ).Child( 0 ).Text();
  781. XmlTest( "White space condensed.", "This has leading, trailing, and internal space", text->Value() );
  782. }
  783. {
  784. // Double attributes
  785. const char* doctype = "<element attr='red' attr='blue' />";
  786. TiXmlDocument doc;
  787. doc.Parse( doctype );
  788. XmlTest( "Parsing repeated attributes.", 0, (int)doc.Error() ); // not an  error to tinyxml
  789. XmlTest( "Parsing repeated attributes.", "blue", doc.FirstChildElement( "element" )->Attribute( "attr" ) );
  790. }
  791. {
  792. // Embedded null in stream.
  793. const char* doctype = "<element attr='red' attr='blue' />";
  794. TiXmlDocument doc;
  795. doc.Parse( doctype );
  796. XmlTest( "Embedded null throws error.", true, doc.Error() );
  797. #ifdef TIXML_USE_STL
  798. istringstream strm( doctype );
  799. doc.Clear();
  800. doc.ClearError();
  801. strm >> doc;
  802. XmlTest( "Embedded null throws error.", true, doc.Error() );
  803. #endif
  804. }
  805.     {
  806.             // Legacy mode test. (This test may only pass on a western system)
  807.             const char* str =
  808.                         "<?xml version="1.0" encoding="ISO-8859-1"?>"
  809.                         "<