@@ -43,8 +43,6 @@ struct XMLParser::Pimpl
43
43
44
44
void loadDocImpl (XMLDocument *doc);
45
45
46
- void verifyXML (const XMLDocument* doc) const ;
47
-
48
46
std::list< std::unique_ptr<XMLDocument> > opened_documents;
49
47
std::unordered_map<std::string,const XMLElement*> tree_roots;
50
48
@@ -166,11 +164,37 @@ void XMLParser::Pimpl::loadDocImpl(XMLDocument* doc)
166
164
}
167
165
tree_roots.insert ( {tree_name, bt_node} );
168
166
}
169
- verifyXML (doc);
167
+
168
+ std::set<std::string> registered_nodes;
169
+ XMLPrinter printer;
170
+ doc->Print (&printer);
171
+ auto xml_text = std::string (printer.CStr (), size_t (printer.CStrSize () - 1 ));
172
+
173
+ for ( const auto & it: factory.manifests ())
174
+ {
175
+ registered_nodes.insert ( it.first );
176
+ }
177
+ for ( const auto & it: tree_roots)
178
+ {
179
+ registered_nodes.insert ( it.first );
180
+ }
181
+
182
+ VerifyXML (xml_text, registered_nodes);
170
183
}
171
184
172
- void XMLParser::Pimpl::verifyXML (const XMLDocument* doc) const
185
+ void VerifyXML (const std::string& xml_text,
186
+ const std::set<std::string>& registered_nodes)
173
187
{
188
+
189
+ XMLDocument doc;
190
+ auto xml_error = doc.Parse ( xml_text.c_str (), xml_text.size ());
191
+ if (xml_error)
192
+ {
193
+ char buffer[200 ];
194
+ sprintf (buffer, " Error parsing the XML: %s" , doc.ErrorName () );
195
+ throw RuntimeError ( buffer );
196
+ }
197
+
174
198
// -------- Helper functions (lambdas) -----------------
175
199
auto StrEqual = [](const char * str1, const char * str2) -> bool {
176
200
return strcmp (str1, str2) == 0 ;
@@ -193,7 +217,7 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
193
217
};
194
218
// -----------------------------
195
219
196
- const XMLElement* xml_root = doc-> RootElement ();
220
+ const XMLElement* xml_root = doc. RootElement ();
197
221
198
222
if (!xml_root || !StrEqual (xml_root->Name (), " root" ))
199
223
{
@@ -205,8 +229,8 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
205
229
206
230
if (meta_sibling)
207
231
{
208
- ThrowError (meta_sibling->GetLineNum (), " Only a single node <TreeNodesModel> is "
209
- " supported" );
232
+ ThrowError (meta_sibling->GetLineNum (),
233
+ " Only a single node <TreeNodesModel> is supported" );
210
234
}
211
235
if (meta_root)
212
236
{
@@ -222,8 +246,8 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
222
246
const char * ID = node->Attribute (" ID" );
223
247
if (!ID)
224
248
{
225
- ThrowError (node->GetLineNum (), " Error at line %d: -> The attribute [ID] is "
226
- " mandatory" );
249
+ ThrowError (node->GetLineNum (),
250
+ " Error at line %d: -> The attribute [ID] is mandatory" );
227
251
}
228
252
}
229
253
}
@@ -240,43 +264,48 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
240
264
{
241
265
if (children_count != 1 )
242
266
{
243
- ThrowError (node->GetLineNum (), " The node <Decorator> must have exactly 1 child" );
267
+ ThrowError (node->GetLineNum (),
268
+ " The node <Decorator> must have exactly 1 child" );
244
269
}
245
270
if (!node->Attribute (" ID" ))
246
271
{
247
- ThrowError (node->GetLineNum (), " The node <Decorator> must have the attribute "
248
- " [ID]" );
272
+ ThrowError (node->GetLineNum (),
273
+ " The node <Decorator> must have the attribute [ID]" );
249
274
}
250
275
}
251
276
else if (StrEqual (name, " Action" ))
252
277
{
253
278
if (children_count != 0 )
254
279
{
255
- ThrowError (node->GetLineNum (), " The node <Action> must not have any child" );
280
+ ThrowError (node->GetLineNum (),
281
+ " The node <Action> must not have any child" );
256
282
}
257
283
if (!node->Attribute (" ID" ))
258
284
{
259
- ThrowError (node->GetLineNum (), " The node <Action> must have the attribute [ID]" );
285
+ ThrowError (node->GetLineNum (),
286
+ " The node <Action> must have the attribute [ID]" );
260
287
}
261
288
}
262
289
else if (StrEqual (name, " Condition" ))
263
290
{
264
291
if (children_count != 0 )
265
292
{
266
- ThrowError (node->GetLineNum (), " The node <Condition> must not have any child" );
293
+ ThrowError (node->GetLineNum (),
294
+ " The node <Condition> must not have any child" );
267
295
}
268
296
if (!node->Attribute (" ID" ))
269
297
{
270
- ThrowError (node->GetLineNum (), " The node <Condition> must have the attribute "
271
- " [ID]" );
298
+ ThrowError (node->GetLineNum (),
299
+ " The node <Condition> must have the attribute [ID]" );
272
300
}
273
301
}
274
302
else if (StrEqual (name, " Sequence" ) || StrEqual (name, " SequenceStar" ) ||
275
303
StrEqual (name, " Fallback" ) || StrEqual (name, " FallbackStar" ))
276
304
{
277
305
if (children_count == 0 )
278
306
{
279
- ThrowError (node->GetLineNum (), " A Control node must have at least 1 child" );
307
+ ThrowError (node->GetLineNum (),
308
+ " A Control node must have at least 1 child" );
280
309
}
281
310
}
282
311
else if (StrEqual (name, " SubTree" ))
@@ -286,25 +315,25 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
286
315
{
287
316
if ( StrEqual (child->Name (), " remap" ) == false )
288
317
{
289
- ThrowError (node->GetLineNum (), " <SubTree> accept only childs of type <remap>" );
318
+ ThrowError (node->GetLineNum (),
319
+ " <SubTree> accept only childs of type <remap>" );
290
320
}
291
321
}
292
322
293
323
if (!node->Attribute (" ID" ))
294
324
{
295
- ThrowError (node->GetLineNum (), " The node <SubTree> must have the attribute [ID]" );
325
+ ThrowError (node->GetLineNum (),
326
+ " The node <SubTree> must have the attribute [ID]" );
296
327
}
297
328
}
298
329
else
299
330
{
300
331
// search in the factory and the list of subtrees
301
- const auto & manifests = factory.manifests ();
302
-
303
- bool found = ( manifests.find (name) != manifests.end () ||
304
- tree_roots.find (name) != tree_roots.end () );
332
+ bool found = ( registered_nodes.find (name) != registered_nodes.end () );
305
333
if (!found)
306
334
{
307
- ThrowError (node->GetLineNum (), std::string (" Node not recognized: " ) + name);
335
+ ThrowError (node->GetLineNum (),
336
+ std::string (" Node not recognized: " ) + name);
308
337
}
309
338
}
310
339
// recursion
@@ -331,7 +360,8 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
331
360
}
332
361
if (ChildrenCount (bt_root) != 1 )
333
362
{
334
- ThrowError (bt_root->GetLineNum (), " The node <BehaviorTree> must have exactly 1 child" );
363
+ ThrowError (bt_root->GetLineNum (),
364
+ " The node <BehaviorTree> must have exactly 1 child" );
335
365
}
336
366
else
337
367
{
@@ -351,9 +381,8 @@ void XMLParser::Pimpl::verifyXML(const XMLDocument* doc) const
351
381
{
352
382
if (tree_count != 1 )
353
383
{
354
- throw RuntimeError (
355
- " If you don't specify the attribute [main_tree_to_execute], "
356
- " Your file must contain a single BehaviorTree" );
384
+ throw RuntimeError (" If you don't specify the attribute [main_tree_to_execute], "
385
+ " Your file must contain a single BehaviorTree" );
357
386
}
358
387
}
359
388
}
0 commit comments