Refactored XML export code between management command and view
Some checks failed
SonarQube Scan / SonarQube Trigger (push) Failing after 56s

This commit is contained in:
2026-01-09 14:18:33 +01:00
parent c77e8c0432
commit b0725fb385
3 changed files with 209 additions and 347 deletions

View File

@@ -9,6 +9,7 @@ from django.utils.safestring import SafeString
import json
import xml.etree.ElementTree as ET
from .models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage, VorgabeComment
from .utils import build_dokument_xml_element, prettify_xml
from abschnitte.utils import render_textabschnitte
from datetime import date
@@ -17,39 +18,6 @@ import parsedatetime
calendar=parsedatetime.Calendar()
def _parse_markdown_table(markdown_content):
"""
Parse markdown table content and return XML element with <table><header><row><column> structure
"""
lines = [line.strip() for line in markdown_content.strip().split('\n') if line.strip()]
if not lines:
return None
# Create table element
table = ET.Element('table')
# Parse first row as header
header_row = [cell.strip() for cell in lines[0].split('|') if cell.strip()]
header = ET.SubElement(table, 'header')
for cell in header_row:
column = ET.SubElement(header, 'column')
column.text = cell
# Parse remaining rows (skip separator row if it exists)
for line in lines[2:] if len(lines) > 1 and all(c in '-| ' for c in lines[1]) else lines[1:]:
# Check if this is a separator row
if all(c in '-| ' for c in line):
continue
row = ET.SubElement(table, 'row')
row_cells = [cell.strip() for cell in line.split('|') if cell.strip()]
for cell in row_cells:
column = ET.SubElement(row, 'column')
column.text = cell
return table
def standard_list(request):
dokumente = Dokument.objects.all()
return render(request, 'standards/standard_list.html',
@@ -295,7 +263,7 @@ def standard_xml(request, nummer):
# Get the document with all related data
dokument = get_object_or_404(
Dokument.objects.prefetch_related(
'autoren', 'pruefende', 'vorgaben__thema',
'autoren', 'pruefende', 'vorgaben__thema',
'vorgaben__referenzen', 'vorgaben__stichworte',
'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
@@ -304,150 +272,21 @@ def standard_xml(request, nummer):
nummer=nummer
)
root = ET.Element('Vorgabendokument')
ET.SubElement(root, 'Typ').text = dokument.dokumententyp.name if dokument.dokumententyp else ""
ET.SubElement(root, 'Nummer').text = dokument.nummer
ET.SubElement(root, 'Name').text = dokument.name
autoren_element = ET.SubElement(root, 'Autoren')
for autor in dokument.autoren.all():
ET.SubElement(autoren_element, 'Autor').text = autor.name
pruefende_element = ET.SubElement(root, 'Pruefende')
for pruefender in dokument.pruefende.all():
ET.SubElement(pruefende_element, 'Pruefender').text = pruefender.name
gueltigkeit_element = ET.SubElement(root, 'Gueltigkeit')
ET.SubElement(gueltigkeit_element, 'Von').text = dokument.gueltigkeit_von.strftime("%Y-%m-%d") if dokument.gueltigkeit_von else ""
ET.SubElement(gueltigkeit_element, 'Bis').text = dokument.gueltigkeit_bis.strftime("%Y-%m-%d") if dokument.gueltigkeit_bis else None
ET.SubElement(root, 'SignaturCSO').text = dokument.signatur_cso
geltungsbereich_sections = dokument.geltungsbereich_set.all().order_by('order')
if geltungsbereich_sections:
geltungsbereich_element = ET.SubElement(root, 'Geltungsbereich')
for gb in geltungsbereich_sections:
section_type = gb.abschnitttyp.abschnitttyp if gb.abschnitttyp else "text"
if section_type in ('tabelle', 'table'):
table = _parse_markdown_table(gb.inhalt)
if table is not None:
abschnitt_element = ET.SubElement(geltungsbereich_element, 'Abschnitt')
abschnitt_element.set('typ', section_type)
abschnitt_element.append(table)
else:
abschnitt_element = ET.SubElement(geltungsbereich_element, 'Abschnitt')
abschnitt_element.set('typ', section_type)
abschnitt_element.text = gb.inhalt
einleitung_sections = dokument.einleitung_set.all().order_by('order')
if einleitung_sections:
einleitung_element = ET.SubElement(root, 'Einleitung')
for ei in einleitung_sections:
section_type = ei.abschnitttyp.abschnitttyp if ei.abschnitttyp else "text"
if section_type in ('tabelle', 'table'):
table = _parse_markdown_table(ei.inhalt)
if table is not None:
abschnitt_element = ET.SubElement(einleitung_element, 'Abschnitt')
abschnitt_element.set('typ', section_type)
abschnitt_element.append(table)
else:
abschnitt_element = ET.SubElement(einleitung_element, 'Abschnitt')
abschnitt_element.set('typ', section_type)
abschnitt_element.text = ei.inhalt
ET.SubElement(root, 'Ziel').text = ""
ET.SubElement(root, 'Grundlagen').text = ""
changelog_element = ET.SubElement(root, 'Changelog')
for cl in dokument.changelog.all().order_by('-datum'):
entry = ET.SubElement(changelog_element, 'Eintrag')
ET.SubElement(entry, 'Datum').text = cl.datum.strftime("%Y-%m-%d")
autoren = ET.SubElement(entry, 'Autoren')
for autor in cl.autoren.all():
ET.SubElement(autoren, 'Autor').text = autor.name
ET.SubElement(entry, 'Aenderung').text = cl.aenderung
anhaenge_element = ET.SubElement(root, 'Anhaenge')
ET.SubElement(anhaenge_element, 'Anhang').text = dokument.anhaenge
ET.SubElement(root, 'Verantwortlich').text = "Information Security Management BIT"
ET.SubElement(root, 'Klassifizierung').text = ""
glossar_element = ET.SubElement(root, 'Glossar')
vorgaben_element = ET.SubElement(root, 'Vorgaben')
for vorgabe in dokument.vorgaben.all().order_by('order'):
vorgabe_el = ET.SubElement(vorgaben_element, 'Vorgabe')
ET.SubElement(vorgabe_el, 'Nummer').text = str(vorgabe.nummer)
ET.SubElement(vorgabe_el, 'Titel').text = vorgabe.titel
ET.SubElement(vorgabe_el, 'Thema').text = vorgabe.thema.name if vorgabe.thema else ""
kurztext_sections = vorgabe.vorgabekurztext_set.all().order_by('order')
if kurztext_sections:
kurztext_element = ET.SubElement(vorgabe_el, 'Kurztext')
for kt in kurztext_sections:
section_type = kt.abschnitttyp.abschnitttyp if kt.abschnitttyp else "text"
if section_type in ('tabelle', 'table'):
table = _parse_markdown_table(kt.inhalt)
if table is not None:
abschnitt = ET.SubElement(kurztext_element, 'Abschnitt')
abschnitt.set('typ', section_type)
abschnitt.append(table)
else:
abschnitt = ET.SubElement(kurztext_element, 'Abschnitt')
abschnitt.set('typ', section_type)
abschnitt.text = kt.inhalt
langtext_sections = vorgabe.vorgabelangtext_set.all().order_by('order')
if langtext_sections:
langtext_element = ET.SubElement(vorgabe_el, 'Langtext')
for lt in langtext_sections:
section_type = lt.abschnitttyp.abschnitttyp if lt.abschnitttyp else "text"
if section_type in ('tabelle', 'table'):
table = _parse_markdown_table(lt.inhalt)
if table is not None:
abschnitt = ET.SubElement(langtext_element, 'Abschnitt')
abschnitt.set('typ', section_type)
abschnitt.append(table)
else:
abschnitt = ET.SubElement(langtext_element, 'Abschnitt')
abschnitt.set('typ', section_type)
abschnitt.text = lt.inhalt
referenz_element = ET.SubElement(vorgabe_el, 'Referenzen')
for ref in vorgabe.referenzen.all():
ref_text = f"{ref.name_nummer}: {ref.name_text}" if ref.name_text else ref.name_nummer
ET.SubElement(referenz_element, 'Referenz').text = ref_text
vorgabe_gueltigkeit = ET.SubElement(vorgabe_el, 'Gueltigkeit')
ET.SubElement(vorgabe_gueltigkeit, 'Von').text = vorgabe.gueltigkeit_von.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_von else ""
ET.SubElement(vorgabe_gueltigkeit, 'Bis').text = vorgabe.gueltigkeit_bis.strftime("%Y-%m-%d") if vorgabe.gueltigkeit_bis else None
checklistenfragen_element = ET.SubElement(vorgabe_el, 'Checklistenfragen')
for cf in vorgabe.checklistenfragen.all():
ET.SubElement(checklistenfragen_element, 'Frage').text = cf.frage
stichworte_element = ET.SubElement(vorgabe_el, 'Stichworte')
for stw in vorgabe.stichworte.all():
ET.SubElement(stichworte_element, 'Stichwort').text = stw.stichwort
# Create a temporary root element to build the document
root = ET.Element('root')
build_dokument_xml_element(dokument, root)
# Get the actual document element (first child of root)
doc_element = root[0]
xml_str = ET.tostring(doc_element, encoding='unicode', method='xml')
xml_output = prettify_xml(xml_str)
xml_str = ET.tostring(root, encoding='unicode', method='xml')
xml_output = _prettify_xml(xml_str)
response = HttpResponse(xml_output, content_type='application/xml; charset=utf-8')
response['Content-Disposition'] = f'attachment; filename="{dokument.nummer}.xml"'
return response
def _prettify_xml(xml_string):
import xml.dom.minidom
dom = xml.dom.minidom.parseString(xml_string)
return dom.toprettyxml(indent=" ", encoding="UTF-8").decode('utf-8')
@login_required
def get_vorgabe_comments(request, vorgabe_id):
"""Get comments for a specific Vorgabe"""