from __future__ import annotations from dataclasses import dataclass, field # ============================================================ # Datastrukturer # ============================================================ @dataclass class XsdChoiceElement: element_navn: str rod_sti: str overliggende: list[str] alternativer: list[tuple[str, str, str]] # (alt_navn, skabelon_navn, fuld_sti) @dataclass class XsdFelt: """ Repræsenterer ét felt i en complexType – enten et element eller en attribut. navn: Feltets navn, fx 'FirstName' eller 'currCode' er_attribut: True hvis det er en XML-attribut (@navn i YAML) xsd_type: Den originale XSD-type, fx 'xsd:string', 'xsd:date' påkrævet: True hvis feltet er obligatorisk er_liste: True hvis feltet kan forekomme flere gange (maxOccurs > 1) er_tekst: True hvis feltet er et simpleContent-element – tekstindholdet er selve værdien og attributterne er metadata (fx MonAmnt_Type) er_choice: True hvis feltet er ét alternativ i en choice """ navn: str er_attribut: bool = False xsd_type: str = "xsd:string" påkrævet: bool = False er_liste: bool = False er_tekst: bool = False er_choice: bool = False xml_navn: str = "" # ← originalt XML-navn, sættes hvis navn omdøbes @property def felt_ref(self) -> str: # Brug xml_navn hvis det er sat (dvs. navn er omdøbt) ref_navn = self.xml_navn if self.xml_navn else self.navn return f"@{ref_navn}" if self.er_attribut else ref_navn @property def yaml_navn(self) -> str: return self.navn @dataclass class XsdSkabelonRef: """ Repræsenterer en reference til en anden navngiven complexType. Bliver til '- skabelon: xxx' i YAML. element_navn: Elementnavnet i XML, fx 'Name', 'Address' skabelon_navn: Det afledte skabelonnavn, fx 'nameperson', 'address' er_liste: True hvis maxOccurs > 1 påkrævet: True hvis minOccurs != 0 er_choice: True hvis elementet er ét alternativ i en choice """ element_navn: str skabelon_navn: str er_liste: bool = False påkrævet: bool = False er_choice: bool = False @property def prefix_felt(self) -> str: return self.element_navn @property def prefix_navn(self) -> str: navn = self.element_navn.lower() return f"{navn.replace('.', '_').replace('-', '_')}_" @dataclass class XsdKompleksType: """ Repræsenterer en navngiven complexType – bliver til en skabelon. navn: Typens navn, fx 'PersonParty_Type' felter: Liste af XsdFelt og/eller XsdSkabelonRef er_ekstern: True hvis typen kommer fra en importeret XSD-fil har_tekst: True hvis typen bruger simpleContent (fx MonAmnt_Type) """ navn: str felter: list[XsdFelt | XsdSkabelonRef] = field(default_factory=list) er_ekstern: bool = False har_tekst: bool = False @dataclass class XsdListeElement: """ Repræsenterer et maxOccurs > 1 element – bliver til en udtræk-fil. element_navn: Elementets navn, fx 'CryptoUsers' type_navn: Navngiven complexType, fx 'CryptoUsers_Type' rod_sti: Fuld dot-separeret sti, fx 'CARF_OECD.CARFBody.CryptoUsers' overliggende: Navne på overliggende liste-elementer felter: Felter fra anonym inline type (kun hvis type_navn er tom) er_simpel: True hvis antal felter < min_felter – foldes ind som join join_i_skabelon: Skabelonnavn der får join-kolonnen """ element_navn: str type_navn: str = "" rod_sti: str = "" overliggende: list[str] = field(default_factory=list) felter: list[XsdFelt | XsdSkabelonRef] = field(default_factory=list) er_simpel: bool = False join_i_skabelon: str = ""