Skip to content

Commit 308f4eb

Browse files
committed
Fix: Support recursive/nested <include> tags in MJCF parser (#529)
1 parent 3a1fec1 commit 308f4eb

1 file changed

Lines changed: 14 additions & 4 deletions

File tree

dm_control/mjcf/parser.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,11 @@ def _parse(xml_root, escape_separators=False,
196196
with debugging.freeze_current_stack_trace():
197197
# Recursively parse any included XML files.
198198
to_include = []
199-
for include_tag in xml_root.findall('include'):
199+
# Unsloth/User Fix: Use .iter() to find ALL include tags, not just root ones.
200+
# We collect them first to avoid issues while modifying the tree.
201+
include_tags = list(xml_root.iter('include'))
202+
203+
for include_tag in include_tags:
200204
try:
201205
# First look for the path to the included XML file in the assets dict.
202206
path_or_xml_string = assets[include_tag.attrib['file']]
@@ -212,9 +216,15 @@ def _parse(xml_root, escape_separators=False,
212216
resolve_references=resolve_references,
213217
assets=assets)
214218
to_include.append(included_mjcf)
215-
# We must remove <include/> tags before parsing the main XML file, since
216-
# these are a schema violation.
217-
xml_root.remove(include_tag)
219+
220+
# Remove the <include/> tag.
221+
# Since we are iterating deeper, we need to find the parent to remove it.
222+
parent = include_tag.getparent()
223+
if parent is not None:
224+
parent.remove(include_tag)
225+
else:
226+
# Fallback for root (though unlikely via iter unless it is self)
227+
xml_root.remove(include_tag)
218228

219229
# Parse the main XML file.
220230
try:

0 commit comments

Comments
 (0)