Skip to content

Commit

Permalink
feat: support <Uebertragungsdatei> tag in AHBs and MIGs (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
hf-kklein authored Dec 5, 2024
1 parent 7226526 commit 20c5d98
Show file tree
Hide file tree
Showing 8 changed files with 2,849 additions and 10 deletions.
11 changes: 8 additions & 3 deletions src/fundamend/reader/ahbreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
_is_format,
_is_segment,
_is_segment_group,
_is_uebertragungsdatei,
)

# pylint:disable=duplicate-code
Expand All @@ -35,10 +36,13 @@

def _to_code(element: ET.Element) -> Code:
assert _is_code(element)
value = element.text
if value is not None:
value = value.strip()
return Code(
name=element.attrib["Name"],
description=element.attrib["Description"] or None,
value=element.text,
value=value,
ahb_status=element.attrib["AHB_Status"],
)

Expand Down Expand Up @@ -220,7 +224,7 @@ def get_anwendungsfaelle(self) -> list[Anwendungsfall]:
def _iter_segments_and_segment_groups(self, element: ET.Element) -> list[SegmentGroup | Segment]:
"""recursive function that builds a list of all segments and segment groups"""
result: list[Segment | SegmentGroup] = []
if _is_anwendungsfall(element) or _is_format(element):
if _is_anwendungsfall(element) or _is_format(element) or _is_uebertragungsdatei(element):
for sub_element in element:
result.extend(self._iter_segments_and_segment_groups(sub_element))
if _is_segment_group(element):
Expand All @@ -231,7 +235,8 @@ def _iter_segments_and_segment_groups(self, element: ET.Element) -> list[Segment

def _read_anwendungsfall(self, original_element: ET.Element) -> Anwendungsfall:
segments_and_groups = []
for element in self._element_tree.getroot():
root = self._element_tree.getroot()
for element in root:
segments_and_groups.extend(self._iter_segments_and_segment_groups(element))
return Anwendungsfall(
pruefidentifikator=original_element.attrib["Pruefidentifikator"],
Expand Down
5 changes: 5 additions & 0 deletions src/fundamend/reader/element_distinction.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,8 @@ def _is_format(element: ET.Element) -> bool:
def _is_anwendungsfall(element: ET.Element) -> bool:
"""returns true iff the element is an AHB anwendungsfall"""
return element.tag == "AWF"


def _is_uebertragungsdatei(element: ET.Element) -> bool:
"""returns true iff the element is an Uebertragsdatei element (usually below the format level)"""
return element.tag == "Uebertragungsdatei"
31 changes: 25 additions & 6 deletions src/fundamend/reader/migreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
_is_data_element_group,
_is_segment,
_is_segment_group,
_is_uebertragungsdatei,
)


Expand Down Expand Up @@ -117,6 +118,13 @@ def _to_segment_group(element: ET.Element) -> SegmentGroup:
)


def _get_first_tag_starting_with_m(element: ET.Element) -> ET.Element:
for elem in element.iter():
if elem.tag.startswith("M_"):
return elem
raise ValueError("No element starting with M_ found")


class MigReader:
"""
Accesses information from an XML based message implementation guide
Expand All @@ -133,26 +141,31 @@ def get_publishing_date(self) -> date:
"""
returns the publishing date of the message implementation guide
"""
raw_value = self._element_tree.getroot().attrib["Veroeffentlichungsdatum"] # e.g. '24.10.2023'
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
raw_value = root.attrib["Veroeffentlichungsdatum"] # e.g. '24.10.2023'
result = datetime.strptime(raw_value, "%d.%m.%Y").date()
return result

def get_author(self) -> str:
"""
returns the author of the message implementation guide
"""
return self._element_tree.getroot().attrib["Author"]
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
return root.attrib["Author"]

def get_version(self) -> str:
"""
returns the version of the message implementation guide
"""
return self._element_tree.getroot().attrib["Versionsnummer"]
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
return root.attrib["Versionsnummer"]

def get_format(self) -> str:
"""returns the format of the message implementation guide, e.g. 'UTILTS'"""
root_tag: str = self._element_tree.getroot().tag
return root_tag.lstrip("M_") # converts 'M_UTILTS' to 'UTILTS'
root = self._element_tree.getroot()
if _is_uebertragungsdatei(root):
root = _get_first_tag_starting_with_m(root)
return root.tag.lstrip("M_") # converts 'M_UTILTS' to 'UTILTS'

def _iter_segments_and_segment_groups(self, element: ET.Element) -> list[SegmentGroup | Segment]:
"""recursive function that builds a list of all segments and segment groups"""
Expand All @@ -168,7 +181,13 @@ def read(self) -> MessageImplementationGuide:
read the entire file and convert it to a MessageImplementationGuid instance
"""
segments_and_groups = []
for index, element in enumerate(self._element_tree.getroot()):
root = self._element_tree.getroot()
if _is_uebertragungsdatei(root):
for elem in root.iter():
if elem.tag.startswith("M_"):
root = elem
break
for index, element in enumerate(root):
if index == 0:
continue
segments_and_groups.extend(self._iter_segments_and_segment_groups(element))
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ deps =
-r requirements.txt
.[tests]
setenv = PYTHONPATH = {toxinidir}/src
commands = python -m pytest --basetemp={envtmpdir} {posargs}
commands = python -m pytest --basetemp={envtmpdir} {posargs} -vv

[testenv:linting]
# the linting environment is called by the Github Action that runs the linter
Expand Down
Loading

0 comments on commit 20c5d98

Please sign in to comment.