Files
udpak_semistruktur/generators/yaml_generator.py
2026-04-07 03:56:43 +02:00

660 lines
28 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
yaml_generator.py
Fælles YAML-generering til brug med udpak_semistruktur.
Importeres af xsd_til_yaml.py, jsonschema_til_yaml.py og elastic_til_yaml.py.
"""
from __future__ import annotations
import os
from generators.schema_dataklasser import XsdFelt, XsdSkabelonRef, XsdKompleksType, XsdListeElement
# ============================================================
# Hjælpefunktioner
# ============================================================
def _find_fælles_prefix(liste_elementer: list) -> int:
if not liste_elementer:
return 0
# Udelad rod-elementet (første element med korteste sti)
alle_stier = [el.rod_sti.split(".") for el in liste_elementer if len(el.rod_sti.split(".")) > 1]
if not alle_stier:
return 0
korteste = min(len(s) for s in alle_stier)
fælles = 0
for i in range(korteste):
if len(set(s[i] for s in alle_stier)) == 1:
fælles += 1
else:
break
return min(fælles, korteste - 1)
def _byg_choice_grupper(liste_elementer: list) -> dict[str, dict]:
"""
Grupperer liste-elementer der deler samme rod op til choice-niveauet.
Returnerer dict: rod_sti → {
'fælles_rod': str,
'valg': [str], # fx ['Entity', 'Individual']
'element_navn': str, # fx 'Address'
'samlet_rod': str # fx 'CARF_OECD...UserID.[Entity, Individual].Address'
}
"""
from collections import defaultdict
grupper: dict[str, list] = defaultdict(list)
for el in liste_elementer:
dele = el.rod_sti.split(".")
# Nøglen er: alt undtagen næstsidste led (choice-leddet)
if len(dele) >= 2:
nøgle = ".".join(dele[:-2]) + "." + dele[-1] # fjern choice-leddet
grupper[nøgle].append(el)
resultat = {}
for nøgle, elementer in grupper.items():
if len(elementer) > 1:
valg = [el.rod_sti.split(".")[-2] for el in elementer]
fælles_rod = ".".join(elementer[0].rod_sti.split(".")[:-2])
element_navn = elementer[0].rod_sti.split(".")[-1]
samlet = f"{fælles_rod}.[{', '.join(valg)}].{element_navn}"
for el in elementer:
resultat[el.rod_sti] = {
'fælles_rod': fælles_rod,
'valg': valg,
'element_navn': element_navn,
'samlet_rod': samlet
}
return resultat
def _anvend_forkortelser(navn: str, forkortelser: dict[str, str]) -> str:
"""Anvender forkortelser case-insensitivt."""
resultat = navn
for langt, kort in forkortelser.items():
resultat = resultat.replace(langt.lower(), kort.lower())
resultat = resultat.replace(langt, kort)
return resultat
def _xsd_type_til_yaml(xsd_type: str) -> dict:
"""Konverterer XSD-type til YAML-attributter."""
t = xsd_type.lower()
if "decimal" in t:
return {"type": "decimal", "decimaler": 2}
if "integer" in t or ("int" in t and "string" not in t):
return {"type": "integer"}
if "boolean" in t:
return {"type": "boolean"}
if "datetime" in t:
return {"type": "date",
"dato_ind": '"%Y-%m-%dT%H:%M:%S"',
"dato_ud": '"SYBASE"'}
if "date" in t:
return {"type": "date",
"dato_ind": '"%Y-%m-%d"',
"dato_ud": '"%d-%m-%Y"'}
return {}
def _skriv_felt(felt: XsdFelt, indryk: str, forkortelser: dict,
liste_navne: set = set(),
fil_navne_index: dict = {}) -> list[str]:
# Tjek på felt_ref ikke navn da navn kan være forkortet
rod_del = felt.felt_ref.split(".")[0] if "." in felt.felt_ref else ""
er_i_liste_fil = rod_del and rod_del in liste_navne
linjer = []
navn = _anvend_forkortelser(felt.yaml_navn, forkortelser)
# if rod_del:
# print(f" DEBUG: rod_del='{rod_del}' er_i_liste_fil={er_i_liste_fil} liste_navne_sample={list(liste_navne)[:5]}")
if er_i_liste_fil:
fil_navn = fil_navne_index.get(rod_del, f"udtræk_{rod_del.lower()}.yaml")
linjer.append(f'')
linjer.append(f'{indryk}# OBS: {rod_del} har sin egen udtræk-fil: {fil_navn}')
linjer.append(f'{indryk}# - navn: {navn}')
linjer.append(f'{indryk}# felt: "{felt.felt_ref}"')
else:
linjer.append(f'')
navn_str = f'"{navn}"' if navn.startswith("#") else navn
linjer.append(f'{indryk}- navn: {navn_str}')
linjer.append(f'{indryk} felt: "{felt.felt_ref}"')
for k, v in _xsd_type_til_yaml(felt.xsd_type).items():
linjer.append(f'{indryk} {k}: {v}')
if felt.påkrævet:
linjer.append(f'{indryk} påkrævet: true')
if felt.er_liste:
linjer.append(f'{indryk} join: true')
linjer.append(f'{indryk} join_separator: ", "')
linjer.append(f'{indryk} # OBS: Kan forekomme flere gange (maxOccurs > 1)')
return linjer
def _skriv_skabelon_ref(ref: XsdSkabelonRef, indryk: str, forkortelser: dict,
liste_navne: set = set(), tomme_skabeloner: set = set(),
fil_navne_index: dict = {}) -> list[str]:
linjer = []
prefix_navn = _anvend_forkortelser(ref.prefix_navn, forkortelser)
# Tjek om prefix_felt matcher et liste-element med eller uden punktum
rod_del = ref.prefix_felt.split(".")[0] if "." in ref.prefix_felt else ref.prefix_felt
er_i_liste_fil = rod_del and rod_del in liste_navne
# Tjek om skabelonen er tom (alle felter udkommenteret)
er_tom_skabelon = ref.skabelon_navn in tomme_skabeloner
if er_i_liste_fil or er_tom_skabelon:
linjer.append(f'')
if er_i_liste_fil:
fil_navn = fil_navne_index.get(rod_del, f"udtræk_{rod_del.lower()}.yaml")
linjer.append(f'{indryk}# OBS: {rod_del} har sin egen udtræk-fil: {fil_navn}')
else:
linjer.append(f'{indryk}# OBS: {ref.skabelon_navn} skabelonen er tom alle felter har egne udtræk-filer')
linjer.append(f'{indryk}# - skabelon: {ref.skabelon_navn}')
linjer.append(f'{indryk}# prefix_felt: {ref.prefix_felt}')
linjer.append(f'{indryk}# prefix_navn: "{prefix_navn}"')
return linjer
if ref.er_choice:
linjer.append(f'')
linjer.append(f'{indryk}# Vælg ét alternativ (choice):')
else:
linjer.append(f'')
linjer.append(f'{indryk}- skabelon: {ref.skabelon_navn}')
linjer.append(f'{indryk} prefix_felt: {ref.prefix_felt}')
linjer.append(f'{indryk} prefix_navn: "{prefix_navn}"')
if ref.er_choice:
linjer.append(f'{indryk} hvis_findes: {ref.prefix_felt}')
if ref.er_liste:
element_basis = ref.element_navn.lower().split(".")[-1]
fil_navn_hint = fil_navne_index.get(
ref.element_navn.split(".")[-1],
f"udtræk_{element_basis}.yaml"
)
linjer.append(f'{indryk} # OBS: Kan forekomme flere gange (maxOccurs > 1).')
linjer.append(f'{indryk} # Overvej om det skal udtrækkes i en separat fil.')
linjer.append(f'{indryk} # Se evt. {fil_navn_hint}')
return linjer
def _har_aktive_felter(kt: XsdKompleksType, liste_navne: set[str]) -> bool:
"""Returnerer True hvis skabelonen har mindst ét aktivt felt
der ikke er udkommenteret fordi det har sin egen udtræk-fil."""
return any(
not (isinstance(f, XsdSkabelonRef) and
(f.prefix_felt.split(".")[0] if "." in f.prefix_felt else f.prefix_felt) in liste_navne)
and not (isinstance(f, XsdFelt) and
(f.felt_ref.split(".")[0] if "." in f.felt_ref else "") in liste_navne)
for f in kt.felter
)
# ============================================================
# Generator: skabeloner.yaml
# ============================================================
def generer_skabeloner_yaml(
komplekse_typer: dict[str, XsdKompleksType],
output_mappe: str,
forkortelser: dict[str, str] = {},
liste_navne: set[str] = set(),
liste_elementer: list = [] # ← tilføj
) -> None:
fælles_prefix_længde = _find_fælles_prefix(liste_elementer)
fil_navne_index: dict[str, str] = {}
for el in liste_elementer:
rod_dele = el.rod_sti.split(".")
unikke_dele = rod_dele[fælles_prefix_længde:] if len(rod_dele) > fælles_prefix_længde else rod_dele
fil_del = _anvend_forkortelser("_".join(unikke_dele).lower(), forkortelser)
# Behold kun første registrering per element-navn
if el.element_navn not in fil_navne_index:
fil_navne_index[el.element_navn] = f"udtræk_{fil_del}.yaml"
linjer = []
linjer.append("# =============================================================================")
linjer.append("# skabeloner.yaml")
linjer.append("#")
linjer.append("# Auto-genereret feltskabeloner fra XSD.")
linjer.append("# Brug prefix_felt og prefix_navn når skabelonen inkluderes.")
linjer.append("# =============================================================================")
linjer.append("")
linjer.append("kolonne_skabeloner:")
linjer.append("")
# Byg sæt af tomme skabeloner
tomme_skabeloner = {
kt.navn.replace("_Type", "").replace("Type", "").lower()
for kt in komplekse_typer.values()
if kt.felter and not kt.er_ekstern and not _har_aktive_felter(kt, liste_navne)
}
relevante = {n: kt for n, kt in komplekse_typer.items()
if kt.felter and not kt.er_ekstern and _har_aktive_felter(kt, liste_navne)}
for type_navn, kt in relevante.items():
skabelon_navn = type_navn.replace("_Type", "").replace("Type", "").lower()
linjer.append(f" # {type_navn}")
if not _har_aktive_felter(kt, liste_navne):
linjer.append(f" {skabelon_navn}: []")
linjer.append("")
continue
linjer.append(f" {skabelon_navn}:")
for felt in kt.felter:
if isinstance(felt, XsdSkabelonRef):
linjer.extend(_skriv_skabelon_ref(
felt, indryk=" ", forkortelser=forkortelser,
liste_navne=liste_navne, tomme_skabeloner=tomme_skabeloner,
fil_navne_index=fil_navne_index
))
elif isinstance(felt, XsdFelt):
linjer.extend(_skriv_felt(
felt, indryk=" ", forkortelser=forkortelser,
liste_navne=liste_navne, fil_navne_index=fil_navne_index
))
linjer.append("")
sti = os.path.join(output_mappe, "skabeloner.yaml")
with open(sti, "w", encoding="utf-8") as f:
f.write("\n".join(linjer))
print(f" Skrev: {sti}")
# ============================================================
# Generator: choice udtræk-filer
# ============================================================
def generer_choice_udtræk_yaml(
choice_elementer: list,
komplekse_typer: dict,
liste_elementer: list,
output_mappe: str,
prefix: str = "udtræk",
forkortelser: dict = {},
db_schema: str = "dbo",
tabel_prefix: str = "",
output_type: str = "begge",
historik: str = "t2"
) -> None:
from generators.schema_dataklasser import XsdChoiceElement, XsdSkabelonRef, XsdFelt
liste_navne = {el.element_navn for el in liste_elementer}
fælles_prefix_længde = _find_fælles_prefix(liste_elementer)
for ce in choice_elementer:
# Find den overliggende komplekse type
overliggende_type = None
rod_element_navn = ce.rod_sti.split(".")[-1]
for el in liste_elementer:
if el.element_navn == rod_element_navn and el.type_navn:
type_navn_rent = el.type_navn.split(":")[-1] if ":" in el.type_navn else el.type_navn
overliggende_type = komplekse_typer.get(type_navn_rent)
break
for alt_navn, alt_skabelon, alt_sti in ce.alternativer:
# Byg filnavn med samme prefix-logik som generer_udtræk_yaml
rod_dele = ce.rod_sti.split(".")
unikke_dele = rod_dele[fælles_prefix_længde:] if len(rod_dele) > fælles_prefix_længde else rod_dele
rod_del_str = _anvend_forkortelser("_".join(unikke_dele).lower(), forkortelser)
alt_forkortet = _anvend_forkortelser(alt_navn.lower(), forkortelser)
fil_del = f"{rod_del_str}_{alt_forkortet}"
fil_navn = f"{prefix}_{fil_del}.yaml"
hvis_finder_sti = f"{ce.element_navn}.{alt_navn}"
prefix_navn = _anvend_forkortelser(
f"{ce.element_navn.lower()}_{alt_navn.lower()}_".replace(".", "_"),
forkortelser
)
linjer = []
linjer.append("# =============================================================================")
linjer.append(f"# {fil_navn}")
linjer.append("#")
linjer.append(f"# Auto-genereret udtræk for {rod_element_navn} {alt_navn} alternativ.")
linjer.append(f"# Rod-sti: {ce.rod_sti}")
linjer.append(f"# Kører kun hvis {hvis_finder_sti} eksisterer i XML.")
if ce.overliggende:
linjer.append("#")
linjer.append("# Udfyld nøgle-skabeloner i nøgler.yaml inden brug.")
linjer.append("# =============================================================================")
linjer.append("")
linjer.append("output_filer:")
linjer.append("")
linjer.append(f" - rod: {ce.rod_sti}")
linjer.append(f" hvis_findes: {hvis_finder_sti}")
linjer.append(f" kolonner:")
# Nøgler
if ce.overliggende:
linjer.append(f" # Nøgler fra overliggende niveauer udfyld i nøgler.yaml")
for ov_navn in ce.overliggende:
skabelon_navn = _anvend_forkortelser(
f"{ov_navn.lower()}_nøgle", forkortelser
)
linjer.append(f" - skabelon: {skabelon_navn}")
linjer.append("")
# Choice-alternativets skabelon
linjer.append(f" # {alt_navn} felter")
linjer.append(f" - skabelon: {alt_skabelon}")
linjer.append(f" prefix_felt: {ce.element_navn}.{alt_navn}")
linjer.append(f' prefix_navn: "{prefix_navn}"')
# Øvrige felter fra den overliggende type
if overliggende_type and overliggende_type.felter:
ikke_choice_felter = [
f for f in overliggende_type.felter
if not (isinstance(f, XsdSkabelonRef) and f.er_choice)
and not (isinstance(f, XsdFelt) and f.er_choice)
]
if ikke_choice_felter:
linjer.append("")
linjer.append(f" # Øvrige felter fra {rod_element_navn}")
for felt in ikke_choice_felter:
if isinstance(felt, XsdSkabelonRef):
linjer.extend(_skriv_skabelon_ref(
felt, " ", forkortelser, liste_navne
))
elif isinstance(felt, XsdFelt):
linjer.extend(_skriv_felt(
felt, " ", forkortelser, liste_navne
))
linjer.append("")
linjer.append(f" outputs:")
if output_type in ("fil", "begge"):
linjer.append(f" - fil_navn: \"{fil_del}_{{yyyy}}{{mm}}{{dd}}.txt\"")
linjer.append(f" overskrifter: true")
linjer.append("")
if output_type in ("tabel", "begge"):
tabel_navn = f"{tabel_prefix}{fil_del}"
linjer.append(f" - tabel:")
linjer.append(f" staging: {db_schema}.{tabel_navn}_tmp")
linjer.append(f" blivende: {db_schema}.{tabel_navn}")
linjer.append(f" historik: {historik}")
linjer.append(f" # TODO: Angiv forretningsnøgler")
linjer.append(f" forretnings_nøgler: [__NØGLE__]")
linjer.append(f" tekniske_nøgler: [løbenummer]")
linjer.append(f" ekstra_kolonner:")
linjer.append(f" - navn: løbenummer")
linjer.append(f' ddl_type: "int identity"')
linjer.append(f" placering: start")
linjer.append("")
sti = os.path.join(output_mappe, fil_navn)
with open(sti, "w", encoding="utf-8") as f:
f.write("\n".join(linjer))
print(f" Skrev: {sti}")
# ============================================================
# Generator: nøgler.yaml
# ============================================================
def generer_nøgler_yaml(
liste_elementer: list[XsdListeElement],
output_mappe: str,
forkortelser: dict[str, str] = {}
) -> None:
# Find unikke overliggende niveauer
overliggende: dict[str, str] = {}
for el in liste_elementer:
rod_dele = el.rod_sti.split(".")
for ov_navn in el.overliggende:
if ov_navn not in overliggende:
try:
idx = rod_dele.index(ov_navn)
overliggende[ov_navn] = ".".join(rod_dele[:idx + 1])
except ValueError:
overliggende[ov_navn] = f"__{ov_navn.upper()}__"
if not overliggende:
return
linjer = []
linjer.append("# =============================================================================")
linjer.append("# nøgler.yaml")
linjer.append("#")
linjer.append("# Nøgle-skabeloner der binder udtræk-filer til overliggende niveauer.")
linjer.append("# UDFYLD: Erstat __FELT__ med den korrekte forretningsnøgle.")
linjer.append("# =============================================================================")
linjer.append("")
linjer.append("kolonne_skabeloner:")
linjer.append("")
for ov_navn, ov_rod_sti in overliggende.items():
skabelon_navn = _anvend_forkortelser(f"{ov_navn.lower()}_nøgle", forkortelser)
linjer.append(f" # Nøgle fra {ov_navn}-niveau")
linjer.append(f" # TODO: Angiv den korrekte forretningsnøgle for {ov_navn}")
linjer.append(f" {skabelon_navn}:")
linjer.append(f" - navn: __FELT__")
linjer.append(f" felt: \"__FELT__\" # fx \"@id\" eller \"nr\"")
linjer.append(f" rod: {ov_rod_sti}")
linjer.append("")
sti = os.path.join(output_mappe, "nøgler.yaml")
with open(sti, "w", encoding="utf-8") as f:
f.write("\n".join(linjer))
print(f" Skrev: {sti}")
def generer_udtræk_yaml(
liste_elementer: list[XsdListeElement],
komplekse_typer: dict[str, XsdKompleksType],
output_mappe: str,
prefix: str = "udtræk",
min_felter: int = 1,
forkortelser: dict[str, str] = {},
db_schema: str = "dbo",
tabel_prefix: str = "",
output_type: str = "begge",
historik: str = "t2"
) -> None:
# Beregn fælles prefix på tværs af alle rod-stier
fælles_prefix_længde = _find_fælles_prefix(liste_elementer)
fil_navne_index: dict[str, str] = {}
for el in liste_elementer:
rod_dele = el.rod_sti.split(".")
unikke_dele = rod_dele[fælles_prefix_længde:] if len(rod_dele) > fælles_prefix_længde else rod_dele
fil_del = _anvend_forkortelser("_".join(unikke_dele).lower(), forkortelser)
if el.element_navn not in fil_navne_index:
fil_navne_index[el.element_navn] = f"udtræk_{fil_del}.yaml"
# Byg choice-grupper til kommentar-generering (ikke filnavne)
choice_grupper = _byg_choice_grupper(liste_elementer)
# Byg sæt af liste-element navne til udkommentering
liste_navne = {el.element_navn for el in liste_elementer}
for el in liste_elementer:
# Byg unikt filnavn fra rod-stien minus fælles prefix
rod_dele = el.rod_sti.split(".")
unikke_dele = rod_dele[fælles_prefix_længde:] if len(rod_dele) > fælles_prefix_længde else rod_dele
fil_del = _anvend_forkortelser(
"_".join(unikke_dele).lower(), forkortelser
)
fil_navn = f"{prefix}_{fil_del}.yaml"
gruppe = choice_grupper.get(el.rod_sti)
linjer = []
linjer.append("# =============================================================================")
linjer.append(f"# {fil_navn}")
linjer.append("#")
linjer.append(f"# Auto-genereret udtræk for {el.element_navn}.")
linjer.append(f"# Rod-sti: {el.rod_sti}")
if el.er_simpel:
linjer.append("#")
linjer.append(f"# OBS: Dette element er simpelt ({el.element_navn} har få felter).")
linjer.append(f"# Det er foldet ind som join-kolonne i skabelon: {el.join_i_skabelon}")
linjer.append(f"# Denne fil er udkommenteret i config fjern udkommentering for fuldt udtræk.")
if el.overliggende:
linjer.append("#")
linjer.append("# Udfyld nøgle-skabeloner i nøgler.yaml inden brug.")
if gruppe:
linjer.append("#")
linjer.append("# OBS: Dette element forekommer i flere choice-grene:")
for valg in gruppe['valg']:
sti = f"{gruppe['fælles_rod']}.{valg}.{gruppe['element_navn']}"
linjer.append(f"# - {sti}")
linjer.append("# Disse kan samles i én fil ved at ændre rod til en rod med varianter:")
linjer.append(f"# rod: {gruppe['samlet_rod']}")
linjer.append("# Tilføj evt. en kolonne til at skelne grenene:")
linjer.append("# - navn: bruger_type")
linjer.append("# type: rod_variant")
linjer.append("# =============================================================================")
linjer.append("")
linjer.append("output_filer:")
linjer.append("")
linjer.append(f" - rod: {el.rod_sti}")
linjer.append(f" kolonner:")
# Nøgler
if el.overliggende:
linjer.append(f" # Nøgler fra overliggende niveauer udfyld i nøgler.yaml")
for ov_navn in el.overliggende:
skabelon_navn = _anvend_forkortelser(
f"{ov_navn.lower()}_nøgle", forkortelser
)
linjer.append(f" - skabelon: {skabelon_navn}")
linjer.append("")
# Felter fra elementets type eller inline felter
type_navn_rent = _strip_prefix(el.type_navn) if el.type_navn else ""
kt = komplekse_typer.get(type_navn_rent)
if kt and kt.felter and not kt.er_ekstern:
skabelon_navn = type_navn_rent.replace("_Type", "").replace("Type", "").lower()
linjer.append(f" # Felter fra {el.element_navn} se skabeloner.yaml")
linjer.append(f" - skabelon: {skabelon_navn}")
elif el.felter:
linjer.append(f" # Felter fra {el.element_navn}")
for felt in el.felter:
if isinstance(felt, XsdSkabelonRef):
linjer.extend(_skriv_skabelon_ref(
felt, " ", forkortelser, liste_navne,
fil_navne_index=fil_navne_index
))
elif isinstance(felt, XsdFelt):
linjer.extend(_skriv_felt(
felt, " ", forkortelser, liste_navne # ← tilføj liste_navne
))
elif el.er_simpel:
linjer.append(f" # Feltets egen værdi")
linjer.append(f" - navn: {el.element_navn}")
linjer.append(f" felt: \".\"")
linjer.append("")
linjer.append(f" outputs:")
if output_type in ("fil", "begge"):
linjer.append(f" - fil_navn: \"{fil_del}_{{yyyy}}{{mm}}{{dd}}.txt\"")
linjer.append(f" overskrifter: true")
linjer.append("")
if output_type in ("tabel", "begge"):
tabel_navn = f"{tabel_prefix}{fil_del}"
linjer.append(f" - tabel:")
linjer.append(f" staging: {db_schema}.{tabel_navn}_tmp")
linjer.append(f" blivende: {db_schema}.{tabel_navn}")
linjer.append(f" historik: {historik}")
linjer.append(f" # TODO: Angiv forretningsnøgler")
linjer.append(f" forretnings_nøgler: [__NØGLE__]")
linjer.append(f" tekniske_nøgler: [løbenummer]")
linjer.append(f" ekstra_kolonner:")
linjer.append(f" - navn: løbenummer")
linjer.append(f' ddl_type: "int identity"')
linjer.append(f" placering: start")
linjer.append("")
linjer.append("")
sti = os.path.join(output_mappe, fil_navn)
with open(sti, "w", encoding="utf-8") as f:
f.write("\n".join(linjer))
print(f" Skrev: {sti}")
# ============================================================
# Generator: config_xxx.yaml
# ============================================================
def generer_hoved_config(
liste_elementer: list[XsdListeElement],
xsd_sti: str,
output_mappe: str,
prefix: str = "udtræk",
forkortelser: dict[str, str] = {}
) -> None:
xsd_basis = os.path.splitext(os.path.basename(xsd_sti))[0]
# Beregn fælles prefix samme logik som generer_udtræk_yaml
fælles_prefix_længde = _find_fælles_prefix(liste_elementer)
linjer = []
linjer.append("# =============================================================================")
linjer.append(f"# config_{xsd_basis}.yaml")
linjer.append("#")
linjer.append("# Auto-genereret hoved-config.")
linjer.append("# Tilpas config-sektionen med korrekte stier og indstillinger.")
linjer.append("# =============================================================================")
linjer.append("")
linjer.append("include:")
linjer.append(" - skabeloner.yaml")
linjer.append(" - nøgler.yaml")
linjer.append("")
normale = []
simple = []
for el in liste_elementer:
rod_dele = el.rod_sti.split(".")
unikke_dele = rod_dele[fælles_prefix_længde:] if len(rod_dele) > fælles_prefix_længde else rod_dele
fil_del = _anvend_forkortelser(
"_".join(unikke_dele).lower(), forkortelser
)
fil = f"{prefix}_{fil_del}.yaml"
if el.er_simpel:
simple.append((fil, el))
else:
normale.append((fil, el))
for fil, _ in normale:
linjer.append(f" - {fil}")
if simple:
linjer.append("")
linjer.append(" # Simple lister foldet ind som join-kolonner i skabelonerne:")
linjer.append(" # Fjern udkommentering for fuldt udtræk i stedet for join.")
for fil, el in simple:
linjer.append(f" # - {fil} (join i skabelon: {el.join_i_skabelon})")
linjer.append("")
linjer.append("config:")
linjer.append(f" input_fil: {xsd_basis}.xml")
linjer.append(" output_path: __OUTPUT_PATH__")
linjer.append(" logfil: log_{yyyy}{mm}{dd}.txt")
linjer.append(" log_niveau: info")
linjer.append(" log_output: begge")
linjer.append(" encoding: utf-8")
linjer.append(' separator: "\\t"')
linjer.append(" skrivetilstand: w")
linjer.append(' dato_ind: "%Y-%m-%d"')
linjer.append(' dato_ud: "%d-%m-%Y"')
sti = os.path.join(output_mappe, f"config_{xsd_basis}.yaml")
with open(sti, "w", encoding="utf-8") as f:
f.write("\n".join(linjer))
print(f" Skrev: {sti}")
def _strip_prefix(type_navn: str) -> str:
if not type_navn or ":" not in type_navn:
return type_navn
prefix, lokalt = type_navn.split(":", 1)
if prefix in ("xs", "xsd"):
return type_navn
return lokalt