parse to strongly typed dict. will map to excel row later

This commit is contained in:
Daniel Roth 2026-04-14 16:37:49 +00:00
parent 9ccbfc2d11
commit 648fff29af
2 changed files with 54 additions and 17 deletions

View file

@ -49,7 +49,7 @@ SAMPLE_XML = """<RdSAP-Report xmlns="https://epbr.digital.communities.gov.uk/xsd
""" """
def test_parse_rdsap_wide_flat_contract(): def test_parse_rdsap_contract():
# arrange + act # arrange + act
result = parse_rdsap(SAMPLE_XML) result = parse_rdsap(SAMPLE_XML)
@ -57,18 +57,28 @@ def test_parse_rdsap_wide_flat_contract():
assert result == { assert result == {
"address": "1, Fake Avenue, Random, AB24 5CD", "address": "1, Fake Avenue, Random, AB24 5CD",
"property_type": "House", "property_type": "House",
# Main Dwelling - floor 0 "building_parts": [
"main_dwelling_floor_index_0_area_m2": 43.61, {
"main_dwelling_floor_index_0_height_m": 2.46, "identifier": "Main Dwelling",
"main_dwelling_floor_index_0_heat_loss_perimeter_m": 25.31, "floors": [
"main_dwelling_floor_index_0_party_wall_length_m": 0.0, {
# Main Dwelling - floor 1 "area_m2": 43.61,
"main_dwelling_floor_index_1_area_m2": 42.33, "height_m": 2.46,
"main_dwelling_floor_index_1_height_m": 2.44, "heat_loss_perimeter_m": 25.31,
"main_dwelling_floor_index_1_heat_loss_perimeter_m": 26.16, "party_wall_length_m": 0.0,
"main_dwelling_floor_index_1_party_wall_length_m": 0.0, },
# Roof (building-level, repeated across floors or stored once) {
"main_dwelling_roof_construction": "4", "area_m2": 42.33,
"main_dwelling_roof_insulation_location": "2", "height_m": 2.44,
"main_dwelling_roof_insulation_thickness": "100mm", "heat_loss_perimeter_m": 26.16,
"party_wall_length_m": 0.0,
},
],
"roof": {
"construction": 4,
"insulation_location": 2,
"insulation_thickness_mm": 100.0,
},
}
],
} }

View file

@ -1,8 +1,35 @@
from typing import Any from typing import Any, List, Optional, TypedDict
from etl.xml_survey_extraction.XmlParser import PROPERTY_TYPE_LOOKUP from etl.xml_survey_extraction.XmlParser import PROPERTY_TYPE_LOOKUP
class Floor(TypedDict):
area_m2: float
height_m: float
heat_loss_perimeter_m: float
party_wall_length_m: float
class Roof(TypedDict, total=False):
construction: int # TODO: map to str
insulation_location: int # TODO: map to str
insulation_thickness_mm: float
class BuildingPart(TypedDict):
identifier: str # e.g. "Main Dwelling", "Extension"
floors: List[Floor]
roof: Optional[Roof]
class SapPropertyDetails(TypedDict):
address: str
property_type: str
building_parts: List[BuildingPart]
# This file should ultimately live somewhere different, probably # This file should ultimately live somewhere different, probably
def parse_rdsap(xml_string: str) -> Any: # TODO: define shape of return object def parse_rdsap(
xml_string: str,
) -> SapPropertyDetails:
raise NotImplementedError raise NotImplementedError