Skip to content

Feature: advanced xml validation#1146

Open
vivoeiva wants to merge 11 commits into
BehaviorTree:masterfrom
vivoeiva:feature/xml-validation
Open

Feature: advanced xml validation#1146
vivoeiva wants to merge 11 commits into
BehaviorTree:masterfrom
vivoeiva:feature/xml-validation

Conversation

@vivoeiva
Copy link
Copy Markdown

I was looking into different BT.CPP xml file examples (at least they look so at the first glance) and found out that some of them are actually not completely valid. Moreover, trying to open them in Groot2 brings it to an endless loop. Sadly there is no obvious way to validate these files, so I'd like to introduce one.
In general, the following functionality is added:

  1. creation of 'generic' xsd file to check against built-ins without any user added nodes.
  2. creation of a Schematron file checking for advanced constraints like TreeNodesModel for Groot2.
  3. tools for generating both.
  4. generated schemas in the repository, these potentially can be automatically updated
  5. and a python script to check any given xml file against them

It also seems that not all xml files in the repository (these that should be valid) pass the validation. I would address it in a different PR if needed.

NB: LLM (Claude) was used to improve and contribute to the code where my knowledge is limited (Schematron in particular). All LLM contributions have been reviewed by me.

vivoeiva and others added 10 commits May 26, 2026 13:11
When generic=true, oneNodeGroup uses xs:any processContents="lax" instead
of a closed xs:choice, allowing unknown custom node elements to pass
validation. Top-level xs:element declarations are also emitted so that lax
processing can still resolve and validate the known built-in node types by name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generates the generic XSD schema from the default factory (built-in nodes
only) and prints it to stdout, suitable for use as a generic static validator
that stays in sync with the built-in node inventory.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
PortsList is an unordered_map so iterating it directly produced XSD
attributes in hash-table order, which varies across runs and platforms.
Sort ports into a std::map before emitting xs:attribute elements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
XSD alone cannot express constraints like "every custom node element used
in a BehaviorTree body must have a matching TreeNodesModel entry"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generates an ISO Schematron schema (btcpp4.sch) complementing the generic XSD

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@vivoeiva
Copy link
Copy Markdown
Author

I'd like to give also some context on results:

./tools/validate_xml.py fuzzing/corpus/bt_corpus/corpus1.xml
fuzzing/corpus/bt_corpus/corpus1.xml validates OK
./tools/validate_xml.py fuzzing/corpus/bt_corpus/corpus2.xml
fuzzing/corpus/bt_corpus/corpus2.xml:5: element Timeout: Schemas validity error : Element 'Timeout', attribute 'timeout_ms': The attribute 'timeout_ms' is not allowed.
fuzzing/corpus/bt_corpus/corpus2.xml:5: element Timeout: Schemas validity error : Element 'Timeout': The attribute 'msec' is required but missing.
fuzzing/corpus/bt_corpus/corpus2.xml fails to validate
./tools/validate_xml.py fuzzing/corpus/bt_corpus/corpus3.xml
fuzzing/corpus/bt_corpus/corpus3.xml:4: element SetBlackboard: Schemas validity error : Element 'SetBlackboard', attribute 'key': The attribute 'key' is not allowed.
fuzzing/corpus/bt_corpus/corpus3.xml:4: element SetBlackboard: Schemas validity error : Element 'SetBlackboard': The attribute 'output_key' is required but missing.
fuzzing/corpus/bt_corpus/corpus3.xml fails to validate
fuzzing/corpus/bt_corpus/corpus3.xml: /root/BehaviorTree/Sequence/SubTree: SubTree ID='SubTree' is not defined in this file.
        (If the definition lives in an included file, add an <include>.)
./tools/validate_xml.py fuzzing/corpus/bt_corpus/corpus4.xml
fuzzing/corpus/bt_corpus/corpus4.xml:5: element ForceSuccess: Schemas validity error : Element 'ForceSuccess': Missing child element(s). Expected is one of ( {*}*, * ).
fuzzing/corpus/bt_corpus/corpus4.xml:6: element ForceFailure: Schemas validity error : Element 'ForceFailure': Missing child element(s). Expected is one of ( {*}*, * ).
fuzzing/corpus/bt_corpus/corpus4.xml fails to validate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant