@@ -408,101 +408,94 @@ void VerifyXML(const std::string& xml_text,
408408 recursiveStep = [&](const XMLElement* node) {
409409 const int children_count = ChildrenCount (node);
410410 const std::string name = node->Name ();
411+ const std::string ID = node->Attribute (" ID" ) ? node->Attribute (" ID" ) : " " ;
412+ const int line_number = node->GetLineNum ();
413+
411414 if (name == " Decorator" )
412415 {
413416 if (children_count != 1 )
414417 {
415- ThrowError (node-> GetLineNum () , " The node <Decorator> must have exactly 1 "
416- " child" );
418+ ThrowError (line_number , " The tag <Decorator> must have exactly 1 "
419+ " child" );
417420 }
418- if (!node-> Attribute ( " ID " ))
421+ if (ID. empty ( ))
419422 {
420- ThrowError (node-> GetLineNum () , " The node <Decorator> must have the "
421- " attribute [ID]" );
423+ ThrowError (line_number , " The tag <Decorator> must have the "
424+ " attribute [ID]" );
422425 }
423426 }
424427 else if (name == " Action" )
425428 {
426429 if (children_count != 0 )
427430 {
428- ThrowError (node-> GetLineNum () , " The node <Action> must not have any "
429- " child" );
431+ ThrowError (line_number , " The tag <Action> must not have any "
432+ " child" );
430433 }
431- if (!node-> Attribute ( " ID " ))
434+ if (ID. empty ( ))
432435 {
433- ThrowError (node-> GetLineNum () , " The node <Action> must have the "
434- " attribute [ID]" );
436+ ThrowError (line_number , " The tag <Action> must have the "
437+ " attribute [ID]" );
435438 }
436439 }
437440 else if (name == " Condition" )
438441 {
439442 if (children_count != 0 )
440443 {
441- ThrowError (node-> GetLineNum () , " The node <Condition> must not have any "
442- " child" );
444+ ThrowError (line_number , " The tag <Condition> must not have any "
445+ " child" );
443446 }
444- if (!node-> Attribute ( " ID " ))
447+ if (ID. empty ( ))
445448 {
446- ThrowError (node-> GetLineNum () , " The node <Condition> must have the "
447- " attribute [ID]" );
449+ ThrowError (line_number , " The tag <Condition> must have the "
450+ " attribute [ID]" );
448451 }
449452 }
450453 else if (name == " Control" )
451454 {
452455 if (children_count == 0 )
453456 {
454- ThrowError (node-> GetLineNum () , " The node <Control> must have at least 1 "
455- " child" );
457+ ThrowError (line_number , " The tag <Control> must have at least 1 "
458+ " child" );
456459 }
457- if (!node-> Attribute ( " ID " ))
460+ if (ID. empty ( ))
458461 {
459- ThrowError (node-> GetLineNum () , " The node <Control> must have the "
460- " attribute [ID]" );
462+ ThrowError (line_number , " The tag <Control> must have the "
463+ " attribute [ID]" );
461464 }
462465 }
463- else if (name == " Sequence" || name == " ReactiveSequence" ||
464- name == " SequenceWithMemory" || name == " Fallback" )
466+ else if (name == " SubTree" )
465467 {
466- if (children_count = = 0 )
468+ if (children_count ! = 0 )
467469 {
468- std::string name_attr;
469- if (node->Attribute (" name" ))
470- {
471- name_attr = " (`" + std::string (node->Attribute (" name" )) + " `)" ;
472- }
473- ThrowError (node->GetLineNum (), std::string (" A Control node must have at least 1 "
474- " child, error in XML node `" ) +
475- node->Name () + name_attr + " `" );
470+ ThrowError (line_number, " <SubTree> should not have any child" );
476471 }
477- }
478- else if (name == " SubTree" )
479- {
480- auto child = node->FirstChildElement ();
481-
482- if (child)
472+ if (ID.empty ())
483473 {
484- if (StrEqual (child->Name (), " remap" ))
485- {
486- ThrowError (node->GetLineNum (), " <remap> was deprecated" );
487- }
488- else
489- {
490- ThrowError (node->GetLineNum (), " <SubTree> should not have any child" );
491- }
474+ ThrowError (line_number, " The tag <SubTree> must have the "
475+ " attribute [ID]" );
492476 }
493-
494- if (!node->Attribute (" ID" ))
477+ if (registered_nodes.count (ID) != 0 )
495478 {
496- ThrowError (node-> GetLineNum () , " The node <SubTree> must have the "
497- " attribute [ID] " );
479+ ThrowError (line_number , " The attribute [ID] of tag <SubTree> must "
480+ " not use the name of a registered Node " );
498481 }
499482 }
500483 else if (name == " BehaviorTree" )
501484 {
485+ if (ID.empty ())
486+ {
487+ ThrowError (line_number, " The tag <BehaviorTree> must have the "
488+ " attribute [ID]" );
489+ }
502490 if (children_count != 1 )
503491 {
504- ThrowError (node->GetLineNum (), " The node <BehaviorTree> must have exactly 1 "
505- " child" );
492+ ThrowError (line_number, " The tag <BehaviorTree> must have exactly 1 "
493+ " child" );
494+ }
495+ if (registered_nodes.count (ID) != 0 )
496+ {
497+ ThrowError (line_number, " The attribute [ID] of tag <BehaviorTree> "
498+ " must not use the name of a registered Node" );
506499 }
507500 }
508501 else
@@ -512,26 +505,31 @@ void VerifyXML(const std::string& xml_text,
512505 bool found = (search != registered_nodes.end ());
513506 if (!found)
514507 {
515- ThrowError (node-> GetLineNum () , std::string (" Node not recognized: " ) + name);
508+ ThrowError (line_number , std::string (" Node not recognized: " ) + name);
516509 }
517510
518511 if (search->second == NodeType::DECORATOR)
519512 {
520513 if (children_count != 1 )
521514 {
522- ThrowError (node-> GetLineNum () ,
515+ ThrowError (line_number ,
523516 std::string (" The node <" ) + name + " > must have exactly 1 child" );
524517 }
525518 }
519+ else if (search->second == NodeType::CONTROL)
520+ {
521+ if (children_count == 0 )
522+ {
523+ ThrowError (line_number,
524+ std::string (" The node <" ) + name + " > must have 1 or more children" );
525+ }
526+ }
526527 }
527528 // recursion
528- if (name != " SubTree" )
529+ for (auto child = node->FirstChildElement (); child != nullptr ;
530+ child = child->NextSiblingElement ())
529531 {
530- for (auto child = node->FirstChildElement (); child != nullptr ;
531- child = child->NextSiblingElement ())
532- {
533- recursiveStep (child);
534- }
532+ recursiveStep (child);
535533 }
536534 };
537535
0 commit comments