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

@@ -1,40 +1,7 @@
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime from dokumente.models import Dokument
from dokumente.models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage from dokumente.utils import build_dokument_xml_element, prettify_xml
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
class Command(BaseCommand): class Command(BaseCommand):
@@ -49,7 +16,7 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
dokumente = Dokument.objects.filter(aktiv=True).prefetch_related( dokumente = Dokument.objects.filter(aktiv=True).prefetch_related(
'autoren', 'pruefende', 'vorgaben__thema', 'autoren', 'pruefende', 'vorgaben__thema',
'vorgaben__referenzen', 'vorgaben__stichworte', 'vorgaben__referenzen', 'vorgaben__stichworte',
'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set', 'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
'vorgaben__vorgabelangtext_set', 'geltungsbereich_set', 'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
@@ -59,147 +26,14 @@ class Command(BaseCommand):
root = ET.Element('Vorgabendokumente') root = ET.Element('Vorgabendokumente')
for dokument in dokumente: for dokument in dokumente:
doc_element = ET.SubElement(root, 'Vorgabendokument') build_dokument_xml_element(dokument, root)
ET.SubElement(doc_element, 'Typ').text = dokument.dokumententyp.name if dokument.dokumententyp else ""
ET.SubElement(doc_element, 'Nummer').text = dokument.nummer
ET.SubElement(doc_element, 'Name').text = dokument.name
autoren_element = ET.SubElement(doc_element, 'Autoren')
for autor in dokument.autoren.all():
ET.SubElement(autoren_element, 'Autor').text = autor.name
pruefende_element = ET.SubElement(doc_element, 'Pruefende')
for pruefender in dokument.pruefende.all():
ET.SubElement(pruefende_element, 'Pruefender').text = pruefender.name
gueltigkeit_element = ET.SubElement(doc_element, '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(doc_element, 'SignaturCSO').text = dokument.signatur_cso
geltungsbereich_sections = dokument.geltungsbereich_set.all().order_by('order')
if geltungsbereich_sections:
geltungsbereich_element = ET.SubElement(doc_element, '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(doc_element, '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(doc_element, 'Ziel').text = ""
ET.SubElement(doc_element, 'Grundlagen').text = ""
changelog_element = ET.SubElement(doc_element, '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(doc_element, 'Anhaenge')
ET.SubElement(anhaenge_element, 'Anhang').text = dokument.anhaenge
ET.SubElement(doc_element, 'Verantwortlich').text = "Information Security Management BIT"
ET.SubElement(doc_element, 'Klassifizierung').text = ""
glossar_element = ET.SubElement(doc_element, 'Glossar')
vorgaben_element = ET.SubElement(doc_element, '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
xml_str = ET.tostring(root, encoding='unicode', method='xml') xml_str = ET.tostring(root, encoding='unicode', method='xml')
xml_output = self._prettify_xml(xml_str) xml_output = prettify_xml(xml_str)
if options['output']: if options['output']:
with open(options['output'], 'w', encoding='utf-8') as f: with open(options['output'], 'w', encoding='utf-8') as f:
f.write(xml_output) f.write(xml_output)
self.stdout.write(self.style.SUCCESS(f'XML exported to {options["output"]}')) self.stdout.write(self.style.SUCCESS(f'XML exported to {options["output"]}'))
else: else:
self.stdout.write(xml_output) self.stdout.write(xml_output)
def _prettify_xml(self, xml_string):
import xml.dom.minidom
dom = xml.dom.minidom.parseString(xml_string)
return dom.toprettyxml(indent=" ", encoding="UTF-8").decode('utf-8')

View File

@@ -1,7 +1,9 @@
""" """
Utility functions for Vorgaben sanity checking Utility functions for Vorgaben sanity checking and XML export
""" """
import datetime import datetime
import xml.etree.ElementTree as ET
import xml.dom.minidom
from django.db.models import Count from django.db.models import Count
from itertools import combinations from itertools import combinations
from dokumente.models import Vorgabe from dokumente.models import Vorgabe
@@ -119,5 +121,192 @@ def format_conflict_report(conflicts, verbose=False):
lines.append(f" Overlap: {overlap_start} to {overlap_end}") lines.append(f" Overlap: {overlap_start} to {overlap_end}")
else: else:
lines.append(f" Overlap starts: {overlap_start} (no end)") lines.append(f" Overlap starts: {overlap_start} (no end)")
return "\n".join(lines) return "\n".join(lines)
# XML Export utilities
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 prettify_xml(xml_string):
"""
Prettify XML string with proper indentation
"""
dom = xml.dom.minidom.parseString(xml_string)
return dom.toprettyxml(indent=" ", encoding="UTF-8").decode('utf-8')
def build_dokument_xml_element(dokument, parent_element):
"""
Build XML element for a single Dokument and append it to parent_element.
Args:
dokument: Dokument instance (should be prefetched with related data)
parent_element: Parent XML element to append to
Returns:
The created document element
"""
doc_element = ET.SubElement(parent_element, 'Vorgabendokument')
ET.SubElement(doc_element, 'Typ').text = dokument.dokumententyp.name if dokument.dokumententyp else ""
ET.SubElement(doc_element, 'Nummer').text = dokument.nummer
ET.SubElement(doc_element, 'Name').text = dokument.name
autoren_element = ET.SubElement(doc_element, 'Autoren')
for autor in dokument.autoren.all():
ET.SubElement(autoren_element, 'Autor').text = autor.name
pruefende_element = ET.SubElement(doc_element, 'Pruefende')
for pruefender in dokument.pruefende.all():
ET.SubElement(pruefende_element, 'Pruefender').text = pruefender.name
gueltigkeit_element = ET.SubElement(doc_element, '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(doc_element, 'SignaturCSO').text = dokument.signatur_cso
geltungsbereich_sections = dokument.geltungsbereich_set.all().order_by('order')
if geltungsbereich_sections:
geltungsbereich_element = ET.SubElement(doc_element, '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(doc_element, '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(doc_element, 'Ziel').text = ""
ET.SubElement(doc_element, 'Grundlagen').text = ""
changelog_element = ET.SubElement(doc_element, '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(doc_element, 'Anhaenge')
ET.SubElement(anhaenge_element, 'Anhang').text = dokument.anhaenge
ET.SubElement(doc_element, 'Verantwortlich').text = "Information Security Management BIT"
ET.SubElement(doc_element, 'Klassifizierung').text = ""
glossar_element = ET.SubElement(doc_element, 'Glossar')
vorgaben_element = ET.SubElement(doc_element, '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
return doc_element

View File

@@ -9,6 +9,7 @@ from django.utils.safestring import SafeString
import json import json
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from .models import Dokument, Vorgabe, VorgabeKurztext, VorgabeLangtext, Checklistenfrage, VorgabeComment 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 abschnitte.utils import render_textabschnitte
from datetime import date from datetime import date
@@ -17,39 +18,6 @@ import parsedatetime
calendar=parsedatetime.Calendar() 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): def standard_list(request):
dokumente = Dokument.objects.all() dokumente = Dokument.objects.all()
return render(request, 'standards/standard_list.html', return render(request, 'standards/standard_list.html',
@@ -295,7 +263,7 @@ def standard_xml(request, nummer):
# Get the document with all related data # Get the document with all related data
dokument = get_object_or_404( dokument = get_object_or_404(
Dokument.objects.prefetch_related( Dokument.objects.prefetch_related(
'autoren', 'pruefende', 'vorgaben__thema', 'autoren', 'pruefende', 'vorgaben__thema',
'vorgaben__referenzen', 'vorgaben__stichworte', 'vorgaben__referenzen', 'vorgaben__stichworte',
'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set', 'vorgaben__checklistenfragen', 'vorgaben__vorgabekurztext_set',
'vorgaben__vorgabelangtext_set', 'geltungsbereich_set', 'vorgaben__vorgabelangtext_set', 'geltungsbereich_set',
@@ -304,150 +272,21 @@ def standard_xml(request, nummer):
nummer=nummer nummer=nummer
) )
root = ET.Element('Vorgabendokument') # Create a temporary root element to build the document
root = ET.Element('root')
ET.SubElement(root, 'Typ').text = dokument.dokumententyp.name if dokument.dokumententyp else "" build_dokument_xml_element(dokument, root)
ET.SubElement(root, 'Nummer').text = dokument.nummer
ET.SubElement(root, 'Name').text = dokument.name # Get the actual document element (first child of root)
doc_element = root[0]
autoren_element = ET.SubElement(root, 'Autoren')
for autor in dokument.autoren.all(): xml_str = ET.tostring(doc_element, encoding='unicode', method='xml')
ET.SubElement(autoren_element, 'Autor').text = autor.name xml_output = prettify_xml(xml_str)
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
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 = HttpResponse(xml_output, content_type='application/xml; charset=utf-8')
response['Content-Disposition'] = f'attachment; filename="{dokument.nummer}.xml"' response['Content-Disposition'] = f'attachment; filename="{dokument.nummer}.xml"'
return response 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 @login_required
def get_vorgabe_comments(request, vorgabe_id): def get_vorgabe_comments(request, vorgabe_id):
"""Get comments for a specific Vorgabe""" """Get comments for a specific Vorgabe"""