Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 1 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 3 | <title>TinyXml: TinyXML Tutorial</title> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 4 | <link href="doxygen.css" rel="stylesheet" type="text/css"> |
| 5 | </head><body> |
| 6 | <!-- Generated by Doxygen 1.4.4 --> |
| 7 | <div class="qindex"><a class="qindex" href="index.html">Main Page</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Class Members</a></div> |
| 8 | <div class="nav"> |
| 9 | <a class="el" href="index.html">index</a></div> |
| 10 | <h1><a class="anchor" name="tutorial0">TinyXML Tutorial</a></h1><h1>Tutorial Preliminary </h1> |
| 11 | <p> |
| 12 | These pages contains a bunch of examples of using TinyXml.<p> |
| 13 | Each demo is written in a standalone function. If you want to try the code, all you need to do is copy/paste the code into a file, then have a main to call it.<p> |
| 14 | So if the example has a function:<p> |
| 15 | <div class="fragment"><pre class="fragment"> void write_simple_doc() |
| 16 | { |
| 17 | ... |
| 18 | } |
| 19 | </pre></div><p> |
| 20 | then the *complete* program you need to try it is:<p> |
| 21 | <div class="fragment"><pre class="fragment"> #include "stdafx.h" // <-- you MIGHT need this |
| 22 | #include "tinyxml.h" // <-- you definitely need this ;) |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 23 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 24 | void write_simple_doc() |
| 25 | { |
| 26 | ... |
| 27 | } |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 28 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 29 | void main( void ) |
| 30 | { |
| 31 | write_simple_doc(); |
| 32 | } |
| 33 | </pre></div><p> |
| 34 | Two example XML datasets/files will be used. The first looks like this:<p> |
| 35 | <div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
| 36 | <Hello>World</Hello> |
| 37 | </pre></div><p> |
| 38 | The other:<p> |
| 39 | <div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
| 40 | <poetry> |
| 41 | <verse> |
| 42 | Alas |
| 43 | Great Whatever |
| 44 | Alas (again) |
| 45 | </verse> |
| 46 | </poetry> |
| 47 | </pre></div><p> |
| 48 | <h1>Getting Started </h1> |
| 49 | <p> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 50 | <h2>Load XML from a file </h2> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 51 | <p> |
| 52 | Loading a file is as simple as:<p> |
| 53 | <div class="fragment"><pre class="fragment"> void load_file( ) |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 54 | { |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 55 | TiXmlDocument doc( "demo.xml" ); |
| 56 | bool loadOkay = doc.LoadFile(); |
| 57 | |
| 58 | if ( loadOkay ) |
| 59 | { |
| 60 | // Your document is loaded - do what you like |
| 61 | // with it. |
| 62 | // |
| 63 | // Here we'll dump the structure to STDOUT, |
| 64 | // just for example |
| 65 | dump_to_stdout( &doc ); |
| 66 | } |
| 67 | else |
| 68 | { |
| 69 | // load failed |
| 70 | } |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 71 | } |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 72 | </pre></div><p> |
| 73 | The ``dump_to_stdout`` function is defined in the section `Dump structure of a Document to STDOUT` below. If you run this program with this XML:<p> |
| 74 | <div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
| 75 | <Hello>World</Hello> |
| 76 | </pre></div><p> |
| 77 | You'll see this:<p> |
| 78 | <div class="fragment"><pre class="fragment"> DOCUMENT |
| 79 | + DECLARATION |
| 80 | + ELEMENT Hello |
| 81 | + TEXT[World] |
| 82 | </pre></div><p> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 83 | <h2>Building Documents Programatically </h2> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 84 | <p> |
| 85 | Example:<p> |
| 86 | <div class="fragment"><pre class="fragment"> void write_simple_doc( ) |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 87 | { |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 88 | // Make xml: <?xml ..><Hello>World</Hello> |
| 89 | TiXmlDocument doc; |
| 90 | TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); |
| 91 | TiXmlElement * element = new TiXmlElement( "Hello" ); |
| 92 | TiXmlText * text = new TiXmlText( "World" ); |
| 93 | element->LinkEndChild( text ); |
| 94 | doc.LinkEndChild( decl ); |
| 95 | doc.LinkEndChild( element ); |
| 96 | |
| 97 | dump_to_stdout( &doc ); |
| 98 | doc.SaveFile( "madeByHand.xml" ); |
| 99 | } |
| 100 | </pre></div><p> |
| 101 | Alternatively:<p> |
| 102 | <div class="fragment"><pre class="fragment"> void write_simple_doc2( ) |
| 103 | { |
| 104 | // same as write_simple_doc1 but add each node |
| 105 | // as early as possible into the tree. |
| 106 | |
| 107 | TiXmlDocument doc; |
| 108 | TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); |
| 109 | doc.LinkEndChild( decl ); |
| 110 | |
| 111 | TiXmlElement * element = new TiXmlElement( "Hello" ); |
| 112 | doc.LinkEndChild( element ); |
| 113 | |
| 114 | TiXmlText * text = new TiXmlText( "World" ); |
| 115 | element->LinkEndChild( text ); |
| 116 | |
| 117 | dump_to_stdout( &doc ); |
| 118 | doc.SaveFile( "madeByHand2.xml" ); |
| 119 | } |
| 120 | </pre></div><p> |
| 121 | Both of these produce the same XML, namely:<p> |
| 122 | <div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
| 123 | <Hello>World</Hello> |
| 124 | </pre></div><p> |
| 125 | Or in structure form:<p> |
| 126 | <div class="fragment"><pre class="fragment"> DOCUMENT |
| 127 | + DECLARATION |
| 128 | + ELEMENT Hello |
| 129 | + TEXT[World] |
| 130 | </pre></div><p> |
| 131 | <h2>Saving Documents to File </h2> |
| 132 | <p> |
| 133 | This function:<p> |
| 134 | <div class="fragment"><pre class="fragment"> void write_simple_doc3( ) |
| 135 | { |
| 136 | // This example courtesy of polocolege |
| 137 | |
| 138 | TiXmlDocument doc; |
| 139 | TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "", "" ); |
| 140 | doc.LinkEndChild( decl ); |
| 141 | |
| 142 | TiXmlElement * element = new TiXmlElement( "Hello" ); |
| 143 | doc.LinkEndChild( element ); |
| 144 | |
| 145 | TiXmlText * text = new TiXmlText( "Opening a new salutation" ); |
| 146 | element->LinkEndChild( text ); |
| 147 | |
| 148 | TiXmlElement * element2 = new TiXmlElement( "Greeting" ); |
| 149 | element->LinkEndChild( element2 ); |
| 150 | |
| 151 | TiXmlText * text2 = new TiXmlText( "How are you?" ); |
| 152 | element2->LinkEndChild( text2 ); |
| 153 | |
| 154 | TiXmlElement * element3 = new TiXmlElement( "Language" ); |
| 155 | element2->LinkEndChild( element3 ); |
| 156 | |
| 157 | TiXmlText * text3 = new TiXmlText( "English" ); |
| 158 | element3->LinkEndChild( text3 ); |
| 159 | |
| 160 | TiXmlElement * element4 = new TiXmlElement( "Exclamation" ); |
| 161 | element->LinkEndChild( element4 ); |
| 162 | |
| 163 | TiXmlText * text4 = new TiXmlText( "You have children!" ); |
| 164 | element4->LinkEndChild( text4 ); |
| 165 | |
| 166 | dump_to_stdout( &doc ); |
| 167 | doc.SaveFile( "madeByHand3.xml" ); |
| 168 | } |
| 169 | </pre></div><p> |
| 170 | Produces this structure:<p> |
| 171 | <div class="fragment"><pre class="fragment"> Document |
| 172 | + Declaration |
| 173 | + Element "Hello" |
| 174 | + Text: [Opening a new salutation] |
| 175 | + Element "Greeting" |
| 176 | + Text: [How are you?] |
| 177 | + Element "Language" |
| 178 | + Text: [English] |
| 179 | + Element "Exclamation" |
| 180 | + Text: [You have children!] |
| 181 | </pre></div><p> |
| 182 | The file ``madeByHand3.xml`` looks exactly like this (including indents):<p> |
| 183 | <div class="fragment"><pre class="fragment"> <?xml version="1.0" ?> |
| 184 | <Hello>Opening a new salutation |
| 185 | <Greeting>How are you? |
| 186 | <Language>English</Language> |
| 187 | </Greeting> |
| 188 | <Exclamation>You have children!</Exclamation> |
| 189 | </Hello> |
| 190 | </pre></div><p> |
| 191 | I was surprised that TinyXml, by default, writes the XML in what other APIs call a "pretty" format - it modifies the whitespace of text of elements that contain other nodes so that writing the tree includes an indication of nesting level.<p> |
| 192 | I haven't looked yet to see if there is a way to turn off indenting when writing a file - its bound to be easy.<p> |
| 193 | [Lee: It's easy in STL mode, just use cout << myDoc. Non-STL mode is always in "pretty" format. Adding a switch would be a nice feature and has been requested.]<p> |
| 194 | <h1>Iterating Over Documents </h1> |
| 195 | <p> |
| 196 | <h2>Dump structure of a Document to STDOUT </h2> |
| 197 | <p> |
| 198 | Often when you're starting its helpful and reassuring to know that you're document got loaded as you expect it to.<p> |
| 199 | Below I've defined a function to walk a document and write contents to STDOUT:<p> |
| 200 | <div class="fragment"><pre class="fragment"> // a utility function defining a very simple method to indent a line of text |
| 201 | const char * getIndent( unsigned int numIndents ) |
| 202 | { |
| 203 | static const char * pINDENT = " + "; |
| 204 | static const unsigned int LENGTH = strlen( pINDENT ); |
| 205 | |
| 206 | if ( numIndents > LENGTH ) numIndents = LENGTH; |
| 207 | |
| 208 | return &pINDENT[ LENGTH-numIndents ]; |
| 209 | } |
| 210 | |
| 211 | void dump_to_stdout( TiXmlNode * pParent, unsigned int indent = 0 ) |
| 212 | { |
| 213 | if ( !pParent ) return; |
| 214 | |
| 215 | TiXmlText *pText; |
| 216 | int t = pParent->Type(); |
| 217 | printf( "%s", getIndent( indent)); |
| 218 | |
| 219 | switch ( t ) |
| 220 | { |
| 221 | case TiXmlNode::DOCUMENT: |
| 222 | printf( "Document" ); |
| 223 | break; |
| 224 | |
| 225 | case TiXmlNode::ELEMENT: |
| 226 | printf( "Element \"%s\"", pParent->Value() ); |
| 227 | break; |
| 228 | |
| 229 | case TiXmlNode::COMMENT: |
| 230 | printf( "Comment: \"%s\"", pParent->Value()); |
| 231 | break; |
| 232 | |
| 233 | case TiXmlNode::UNKNOWN: |
| 234 | printf( "Unknown" ); |
| 235 | break; |
| 236 | |
| 237 | case TiXmlNode::TEXT: |
| 238 | pText = pParent->ToText(); |
| 239 | printf( "Text: [%s]", pText->Value() ); |
| 240 | break; |
| 241 | |
| 242 | case TiXmlNode::DECLARATION: |
| 243 | printf( "Declaration" ); |
| 244 | break; |
| 245 | default: |
| 246 | break; |
| 247 | } |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 248 | printf( "\n" ); |
Dan Albert | c3bbea3 | 2014-08-21 15:48:37 -0700 | [diff] [blame] | 249 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 250 | TiXmlNode * pChild; |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 251 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 252 | for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) |
| 253 | { |
| 254 | dump_to_stdout( pChild, indent+2 ); |
| 255 | } |
Dan Albert | c3bbea3 | 2014-08-21 15:48:37 -0700 | [diff] [blame] | 256 | } |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 257 | </pre></div><p> |
| 258 | To load a file and dump its structure:<p> |
| 259 | <div class="fragment"><pre class="fragment"> void load_and_display( ) |
| 260 | { |
| 261 | // important for the poetry demo, but you may not need this |
| 262 | // in your own projects |
| 263 | TiXmlBase::SetCondenseWhiteSpace( false ); |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 264 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 265 | TiXmlDocument doc( "demo.xml" ); |
| 266 | bool loadOkay = doc.LoadFile(); |
Dan Albert | c3bbea3 | 2014-08-21 15:48:37 -0700 | [diff] [blame] | 267 | |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 268 | if ( loadOkay ) |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 269 | { |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 270 | dump_to_stdout( &doc ); |
| 271 | } |
| 272 | else |
| 273 | { |
| 274 | printf( "Something went wrong\n" ); |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 275 | } |
| 276 | } |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 277 | </pre></div><p> |
| 278 | If you run this with the first XML file you'll see this on STDOUT:<p> |
| 279 | <div class="fragment"><pre class="fragment"> DOCUMENT |
| 280 | + DECLARATION |
| 281 | + ELEMENT Hello |
| 282 | + TEXT[World] |
| 283 | </pre></div><p> |
| 284 | and on the second XML file:<p> |
| 285 | <div class="fragment"><pre class="fragment"> DOCUMENT |
| 286 | + DECLARATION |
| 287 | + ELEMENT poetry |
| 288 | + COMMENT: my great work of art |
| 289 | + ELEMENT verse |
| 290 | + TEXT[ |
| 291 | Alas |
| 292 | Great Whatever |
| 293 | Alas (again) |
| 294 | ] |
| 295 | </pre></div><p> |
| 296 | Note that if you call dump_to_stdout like this:<p> |
| 297 | <div class="fragment"><pre class="fragment"> dump_to_stdout( doc.RootElement()); |
| 298 | </pre></div><p> |
| 299 | You'll see this instead:<p> |
| 300 | <div class="fragment"><pre class="fragment"> ELEMENT Hello |
| 301 | + TEXT[World] |
| 302 | </pre></div><p> |
| 303 | and:<p> |
| 304 | <div class="fragment"><pre class="fragment"> ELEMENT poetry |
| 305 | + COMMENT: my great work of art |
| 306 | + ELEMENT verse |
| 307 | + TEXT[ |
| 308 | Alas |
| 309 | Great Whatever |
| 310 | Alas (again) |
| 311 | ] |
| 312 | </pre></div><p> |
| 313 | <em> Authors and Changes <ul> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 314 | <li> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 315 | Written by Ellers, April 2005 </li> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 316 | <li> |
| 317 | Minor edits and integration into doc system, Lee Thomason September 2005 </li> |
| 318 | </ul> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 319 | </em> <hr size="1"><address style="align: right;"><small>Generated on Sat Oct 8 14:15:30 2005 for TinyXml by |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 320 | <a href="http://www.doxygen.org/index.html"> |
Dan Albert | 0238a20 | 2014-08-22 00:52:41 +0000 | [diff] [blame] | 321 | <img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.4 </small></address> |
The Android Open Source Project | 562be06 | 2009-03-03 19:30:48 -0800 | [diff] [blame] | 322 | </body> |
| 323 | </html> |