This repository has been archived by the owner on Jul 11, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathtutorial_ticpp.txt
220 lines (174 loc) · 5.6 KB
/
tutorial_ticpp.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/**
@page ticppTutorial TinyXML++ Tutorial
Take a look here @subpage ticpp
This is a work in progress.
@page ticpp TinyXML++
<h2> General Concepts </h2>
The TinyXML++ classes are all wrappers around the corresponding classes within TinyXML.
There is no reason to create TinyXML++ objects on the heap, using @p new, because the memory is managed for you. If you choose
to use @p new to create TinyXML++ objects, you will @b always need to use @p delete to clean up.
Basically, TinyXML++ objects are just wrappers around TinyXML pointers.
<h2> Goals </h2>
- Simplify the use and interface of TinyXml, using C++ concepts.
- Use exceptions for error handling, so there are no return codes to check
- Use templates for automatic type conversion
- Use STL style iterators to move through nodes and attributes
<h2> Details </h2>
<h3> Use exceptions for error handling </h3>
When using the original TinyXML, every function returns a value indicating
success or failure. A programmer would have to check that value to ensure
the function succeeded.
Example:
@code
// Load a document
TiXmlDocument doc( pFilename );
if ( !doc.LoadFile() ) return;
// Get a node
TiXmlElement* pElem = doc.FirstChildElement();
if ( !pElem ) return;
// Get the node we want
pElem = pElem->NextSibling();
if ( !pElem ) return;
// do something useful here
@endcode
An alternative was to use TiXmlHandle, which allows for function chaining by
checking the intermediate function return values:
Example:
@code
// Load a document
TiXmlDocument doc(pFilename);
if (!doc.LoadFile()) return;
// Make a document handle
TiXmlHandle hDoc(&doc);
// Get an element by using the handle to chain calls
// Note the conversion of the TiXmlHandle to the TiXmlElement* - .Element()
TiXmlElement* pElem = hDoc.FirstChildElement().NextSibling().Element();
if ( !pElem ) return;
// do something useful here
@endcode
With TinyXML++, if there is an error during a function call, it throws an exception.
This means that a programmer can assume that every function is successful, as
long as the functions are enclosed in a try-catch block.
Example:
@code
try
{
// Load a document
ticpp::Document doc( pFilename );
doc.LoadFile();
// Get an element by chaining calls - no return values to check, no TiXmlHandle
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
// do something useful here
}
catch( ticpp::Exception& ex )
{
// If any function has an error, execution will enter here.
// Report the error
std::cout << ex.what();
}
@endcode
<h3> Use templates for automatic type conversion </h3>
When using TinyXML, a programmer either needs to convert values to and from
strings, or choose from one of many overloads to get the value in the desired
type.
Example:
@code
// Load a document
TiXmlDocument doc( pFilename );
if ( !doc.LoadFile() ) return;
// Get a node
TiXmlElement* pElem = doc.FirstChildElement();
if ( !pElem ) return;
// Get the node we want
pElem = pElem->NextSibling();
if ( !pElem ) return;
// Get the attribute as a string, convert to int
const char* pszAttr = pElem->Attribute( "myAttribute" );
int attr = atoi( pszAttr );
// Get the attribute as an int
int attr2;
if ( TIXML_SUCCESS != pElem->QueryIntAttribute( "myAttribute", &attr2 ) )
{
return;
}
// Get the attribute as a double
double attr3;
if ( TIXML_SUCCESS != pElem->QueryDoubleAttribute( "myAttribute", &attr3 ) )
{
return;
}
// Get the attribute as a float
float attr4;
if ( TIXML_SUCCESS != pElem->QueryFloatAttribute( "myAttribute", &attr4 ) )
{
return;
}
@endcode
TinyXML++ uses templates for automatic type conversion.
Example:
@code
try
{
// Load a document
ticpp::Document doc( pFilename );
doc.LoadFile();
// Get an element by chaining calls - no return values to check, no TiXmlHandle
ticpp::Element* pElem = doc.FirstChildElement()->NextSibling();
// GetAttribute can determine the type of the pointer, and convert automatically
// Get the attribute as a string
std::string attr;
pElem->GetAttribute( "myAttribute", &attr );
// Get the attribute as an int
int attr2;
pElem->GetAttribute( "myAttribute", &attr2 );
// Get the attribute as an float
float attr3;
pElem->GetAttribute( "myAttribute", &attr3 );
// Get the attribute as an double
double attr4;
pElem->GetAttribute( "myAttribute", &attr4 );
// Get the attribute as an bool
bool attr5;
pElem->GetAttribute( "myAttribute", &attr5 );
}
catch( ticpp::Exception& ex )
{
// If any function has an error, execution will enter here.
// Report the error
std::cout << ex.what();
}
@endcode
<h3> Use STL style iterators to move through nodes and attributes </h3>
TinyXML has two ways to iterate:
First Method:
@code
for( child = parent->FirstChild( false ); child; child = child->NextSibling( false ) )
@endcode
Second Method:
@code
child = 0;
while( child = parent->IterateChildren( child ) )
@endcode
Although both methods work quite well, the syntax is not familiar.
TinyXML++ introduces iterators:
@code
ticpp::Iterator< ticpp::Node > child;
for ( child = child.begin( parent ); child != child.end(); child++ )
@endcode
Iterators have the added advantage of filtering by type:
@code
// Only iterates through Comment nodes
ticpp::Iterator< ticpp::Comment > child;
for ( child = child.begin( parent ); child != child.end(); child++ )
@endcode
@code
// Only iterates through Element nodes with value "ElementValue"
ticpp::Iterator< ticpp::Element > child( "ElementValue" );
for ( child = child.begin( parent ); child != child.end(); child++ )
@endcode
Finally, Iterators also work with Attributes
@code
ticpp::Iterator< ticpp::Attribute > attribute;
for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
@endcode
*/