From 1a3624f3e0b43b5f71645434cd72fbad50702667 Mon Sep 17 00:00:00 2001 From: Mikhail Date: Fri, 14 Aug 2026 13:34:10 +0300 Subject: [PATCH] Decode appearance template style rules --- plugins/1c/parser/appearance_payload.py | 15 +++++++++++++++ tests/1c/test_payload_codec.py | 5 +++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/plugins/1c/parser/appearance_payload.py b/plugins/1c/parser/appearance_payload.py index c943421..f6feb96 100644 --- a/plugins/1c/parser/appearance_payload.py +++ b/plugins/1c/parser/appearance_payload.py @@ -51,11 +51,26 @@ def inspect_appearance_payload(data: bytes) -> dict[str, Any]: for ordinal, item in enumerate((node for node in root if _local_name(node.tag) == "item"), start=1): parameter, value = _child_text(item, "parameter"), _child_text(item, "value") items.append({"ordinal": ordinal, "parameter": parameter, "value": value}) + appearances = [] + for ordinal, appearance in enumerate((node for node in root.iter() if _local_name(node.tag) == "appearance"), start=1): + rules = [] + for item in (node for node in appearance if _local_name(node.tag) == "item"): + value_node = next((child for child in item if _local_name(child.tag) == "value"), None) + rule: dict[str, Any] = {"parameter": _child_text(item, "parameter"), "value": _child_text(item, "value")} + if value_node is not None: + value_type = value_node.attrib.get("{http://www.w3.org/2001/XMLSchema-instance}type") or value_node.attrib.get("type") + if value_type: + rule["value_type"] = value_type + if value_node.attrib: + rule["value_attributes"] = {key.rsplit("}", 1)[-1]: value for key, value in value_node.attrib.items()} + rules.append(rule) + appearances.append({"ordinal": ordinal, "rules": rules}) tag_counts = Counter(_local_name(node.tag) for node in root.iter()) return { "status": "ok", "container": {"compression": decoded.get("compression"), "raw_bytes": decoded.get("raw_bytes"), "payload_bytes": decoded.get("payload_bytes"), "xml_offset": start, "xml_bytes": len(xml_bytes), "xml_root": "AppearanceTemplate"}, "items": items, + "appearances": appearances, "outline": {"tag_counts": dict(sorted(tag_counts.items(), key=lambda item: item[0].casefold()))}, "diagnostics": {"write": "unsupported_until_reverse_codec_fixture"}, } diff --git a/tests/1c/test_payload_codec.py b/tests/1c/test_payload_codec.py index 43eb844..d343a17 100644 --- a/tests/1c/test_payload_codec.py +++ b/tests/1c/test_payload_codec.py @@ -259,13 +259,14 @@ def test_scd_payload_decoder_reads_xml_after_platform_prefix() -> None: def test_appearance_payload_decoder_reads_xml_rules() -> None: xml = """ -Заголовокstyle:Title""" +Заголовокstyle:TitleЦветФонаstyle:Blue""" result = inspect_appearance_payload(compress_payload(b"\x00\x01" + xml.encode("utf-8"), "raw_deflate")) assert result["status"] == "ok" assert result["items"] == [{"ordinal": 1, "parameter": "Заголовок", "value": "style:Title"}] - assert result["outline"]["tag_counts"] == {"AppearanceTemplate": 1, "item": 1, "name": 1, "parameter": 1, "style": 1, "value": 1} + assert result["appearances"] == [{"ordinal": 1, "rules": [{"parameter": "ЦветФона", "value": "style:Blue", "value_type": "Color", "value_attributes": {"type": "Color", "ref": "style:Blue"}}]}] + assert result["outline"]["tag_counts"] == {"AppearanceTemplate": 1, "appearance": 1, "item": 2, "name": 1, "parameter": 2, "style": 1, "value": 2} assert result["diagnostics"]["write"] == "unsupported_until_reverse_codec_fixture"