Skip to content

Commit 20c5d98

Browse files
authored
feat: support <Uebertragungsdatei> tag in AHBs and MIGs (#58)
1 parent 7226526 commit 20c5d98

8 files changed

+2849
-10
lines changed

src/fundamend/reader/ahbreader.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
_is_format,
2828
_is_segment,
2929
_is_segment_group,
30+
_is_uebertragungsdatei,
3031
)
3132

3233
# pylint:disable=duplicate-code
@@ -35,10 +36,13 @@
3536

3637
def _to_code(element: ET.Element) -> Code:
3738
assert _is_code(element)
39+
value = element.text
40+
if value is not None:
41+
value = value.strip()
3842
return Code(
3943
name=element.attrib["Name"],
4044
description=element.attrib["Description"] or None,
41-
value=element.text,
45+
value=value,
4246
ahb_status=element.attrib["AHB_Status"],
4347
)
4448

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

232236
def _read_anwendungsfall(self, original_element: ET.Element) -> Anwendungsfall:
233237
segments_and_groups = []
234-
for element in self._element_tree.getroot():
238+
root = self._element_tree.getroot()
239+
for element in root:
235240
segments_and_groups.extend(self._iter_segments_and_segment_groups(element))
236241
return Anwendungsfall(
237242
pruefidentifikator=original_element.attrib["Pruefidentifikator"],

src/fundamend/reader/element_distinction.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,8 @@ def _is_format(element: ET.Element) -> bool:
4646
def _is_anwendungsfall(element: ET.Element) -> bool:
4747
"""returns true iff the element is an AHB anwendungsfall"""
4848
return element.tag == "AWF"
49+
50+
51+
def _is_uebertragungsdatei(element: ET.Element) -> bool:
52+
"""returns true iff the element is an Uebertragsdatei element (usually below the format level)"""
53+
return element.tag == "Uebertragungsdatei"

src/fundamend/reader/migreader.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
_is_data_element_group,
2222
_is_segment,
2323
_is_segment_group,
24+
_is_uebertragungsdatei,
2425
)
2526

2627

@@ -117,6 +118,13 @@ def _to_segment_group(element: ET.Element) -> SegmentGroup:
117118
)
118119

119120

121+
def _get_first_tag_starting_with_m(element: ET.Element) -> ET.Element:
122+
for elem in element.iter():
123+
if elem.tag.startswith("M_"):
124+
return elem
125+
raise ValueError("No element starting with M_ found")
126+
127+
120128
class MigReader:
121129
"""
122130
Accesses information from an XML based message implementation guide
@@ -133,26 +141,31 @@ def get_publishing_date(self) -> date:
133141
"""
134142
returns the publishing date of the message implementation guide
135143
"""
136-
raw_value = self._element_tree.getroot().attrib["Veroeffentlichungsdatum"] # e.g. '24.10.2023'
144+
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
145+
raw_value = root.attrib["Veroeffentlichungsdatum"] # e.g. '24.10.2023'
137146
result = datetime.strptime(raw_value, "%d.%m.%Y").date()
138147
return result
139148

140149
def get_author(self) -> str:
141150
"""
142151
returns the author of the message implementation guide
143152
"""
144-
return self._element_tree.getroot().attrib["Author"]
153+
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
154+
return root.attrib["Author"]
145155

146156
def get_version(self) -> str:
147157
"""
148158
returns the version of the message implementation guide
149159
"""
150-
return self._element_tree.getroot().attrib["Versionsnummer"]
160+
root = self._element_tree.getroot() # might be either <M_FORMAT> or <Uebertragungsdatei>
161+
return root.attrib["Versionsnummer"]
151162

152163
def get_format(self) -> str:
153164
"""returns the format of the message implementation guide, e.g. 'UTILTS'"""
154-
root_tag: str = self._element_tree.getroot().tag
155-
return root_tag.lstrip("M_") # converts 'M_UTILTS' to 'UTILTS'
165+
root = self._element_tree.getroot()
166+
if _is_uebertragungsdatei(root):
167+
root = _get_first_tag_starting_with_m(root)
168+
return root.tag.lstrip("M_") # converts 'M_UTILTS' to 'UTILTS'
156169

157170
def _iter_segments_and_segment_groups(self, element: ET.Element) -> list[SegmentGroup | Segment]:
158171
"""recursive function that builds a list of all segments and segment groups"""
@@ -168,7 +181,13 @@ def read(self) -> MessageImplementationGuide:
168181
read the entire file and convert it to a MessageImplementationGuid instance
169182
"""
170183
segments_and_groups = []
171-
for index, element in enumerate(self._element_tree.getroot()):
184+
root = self._element_tree.getroot()
185+
if _is_uebertragungsdatei(root):
186+
for elem in root.iter():
187+
if elem.tag.startswith("M_"):
188+
root = elem
189+
break
190+
for index, element in enumerate(root):
172191
if index == 0:
173192
continue
174193
segments_and_groups.extend(self._iter_segments_and_segment_groups(element))

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ deps =
1616
-r requirements.txt
1717
.[tests]
1818
setenv = PYTHONPATH = {toxinidir}/src
19-
commands = python -m pytest --basetemp={envtmpdir} {posargs}
19+
commands = python -m pytest --basetemp={envtmpdir} {posargs} -vv
2020

2121
[testenv:linting]
2222
# the linting environment is called by the Github Action that runs the linter

0 commit comments

Comments
 (0)