Extract managed form elements from XML
CI / python (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-05-21 06:10:05 +03:00
parent 5bd188fe6f
commit af900e4e34
9 changed files with 186 additions and 46 deletions
@@ -19,15 +19,20 @@ def form_semantics(snapshot: SirSnapshot) -> list[FormSemantics]:
for node in snapshot.nodes
if node.kind == NodeKind.FORM
}
element_children: dict[str, list[SemanticNode]] = {}
for edge in snapshot.edges:
form = forms.get(edge.source_lineage)
target = nodes.get(edge.target_lineage)
if form is None or target is None:
if target is None:
continue
if edge.kind == EdgeKind.HAS_ELEMENT and target.kind == NodeKind.FORM_ELEMENT:
element_children.setdefault(edge.source_lineage, []).append(target)
if form is None:
continue
if edge.kind == EdgeKind.HAS_COMMAND:
form.commands.append(target)
elif edge.kind == EdgeKind.HAS_ELEMENT:
form.elements.append(target)
for form in forms.values():
form.elements.extend(_flatten_form_elements(form.form.lineage_id, element_children))
command_to_form = {
command.lineage_id: form
for form in forms.values()
@@ -43,4 +48,20 @@ def form_semantics(snapshot: SirSnapshot) -> list[FormSemantics]:
return sorted(forms.values(), key=lambda item: item.form.qualified_name)
def _flatten_form_elements(root_lineage: str, element_children: dict[str, list[SemanticNode]]) -> list[SemanticNode]:
result: list[SemanticNode] = []
seen: set[str] = set()
def visit(parent_lineage: str) -> None:
for element in element_children.get(parent_lineage, []):
if element.lineage_id in seen:
continue
seen.add(element.lineage_id)
result.append(element)
visit(element.lineage_id)
visit(root_lineage)
return result
__all__ = ["FormSemantics", "form_semantics"]