Expose SCD XML structure outline
This commit is contained in:
@@ -75,22 +75,20 @@ def query_without_line_comments(text: str) -> str:
|
||||
def node_path(root: ET.Element, target: ET.Element) -> str:
|
||||
"""Produce a stable, human-readable evidence path without XML prefixes."""
|
||||
|
||||
def visit(node: ET.Element, prefix: str) -> str | None:
|
||||
name = local_name(node.tag)
|
||||
current = f"{prefix}/{name}" if prefix else f"/{name}"
|
||||
def visit(node: ET.Element, current: str) -> str | None:
|
||||
if node is target:
|
||||
return current
|
||||
positions: dict[str, int] = {}
|
||||
for child in node:
|
||||
child_name = local_name(child.tag)
|
||||
positions[child_name] = positions.get(child_name, 0) + 1
|
||||
child_prefix = f"{current}[{positions[child_name]}]"
|
||||
found = visit(child, child_prefix)
|
||||
suffix = f"[{positions[child_name]}]" if positions[child_name] > 1 else ""
|
||||
found = visit(child, f"{current}/{child_name}{suffix}")
|
||||
if found:
|
||||
return found
|
||||
return None
|
||||
|
||||
return visit(root, "") or "/"
|
||||
return visit(root, f"/{local_name(root.tag)}[1]") or "/"
|
||||
|
||||
|
||||
def xml_from_scd_payload(data: bytes) -> tuple[ET.Element | None, dict[str, Any]]:
|
||||
@@ -184,6 +182,21 @@ def inspect_scd_payload(data: bytes, *, sections: list[str] | None = None) -> di
|
||||
"container": {**container, "code": "SCD_SCHEMA_NODE_NOT_FOUND"},
|
||||
"sections": {name: [] for name in requested},
|
||||
}
|
||||
# Keep a complete, evidence-backed map of the XML shape alongside the
|
||||
# curated semantic sections below. 1C releases and SCD variants may add
|
||||
# nodes that this adapter does not yet assign a business meaning to. A
|
||||
# tag/count/path outline makes those nodes visible to callers without
|
||||
# guessing that (for example) a form property is a dataset or layout.
|
||||
top_level_counts: dict[str, int] = {}
|
||||
top_level_paths: dict[str, list[str]] = {}
|
||||
for child in schema:
|
||||
tag = local_name(child.tag)
|
||||
top_level_counts[tag] = top_level_counts.get(tag, 0) + 1
|
||||
top_level_paths.setdefault(tag, []).append(node_path(schema, child))
|
||||
xml_tag_counts: dict[str, int] = {}
|
||||
for node in schema.iter():
|
||||
tag = local_name(node.tag)
|
||||
xml_tag_counts[tag] = xml_tag_counts.get(tag, 0) + 1
|
||||
node_names = {
|
||||
"parameters": {"parameter"},
|
||||
"datasets": {"dataSet"},
|
||||
@@ -220,6 +233,14 @@ def inspect_scd_payload(data: bytes, *, sections: list[str] | None = None) -> di
|
||||
query_references.append({"dataset": dataset.get("name"), "parameters": references})
|
||||
analysis = {
|
||||
"kind": "raw_query_parameter_token_scan",
|
||||
"schema_outline": {
|
||||
"kind": "exact_xml_tag_inventory",
|
||||
"top_level": [
|
||||
{"tag": tag, "count": top_level_counts[tag], "paths": top_level_paths[tag]}
|
||||
for tag in sorted(top_level_counts, key=str.casefold)
|
||||
],
|
||||
"all_tag_counts": dict(sorted(xml_tag_counts.items(), key=lambda item: item[0].casefold())),
|
||||
},
|
||||
"declared_parameters": declared,
|
||||
"query_parameter_references": query_references,
|
||||
"referenced_not_declared_in_schema": sorted(
|
||||
|
||||
Reference in New Issue
Block a user