From 330f391a489b7cacc0a8d6309466ddd9d860b66b Mon Sep 17 00:00:00 2001 From: Tobias Langer Date: Wed, 14 Feb 2024 19:53:58 +0100 Subject: [PATCH] Fix missing text in element error for Python (#443) Since the XMLPullParser doesn't guarantee that the attributes of a start events are populated. When the parser has not yet encountered the text event, this attribute will be None. Instead we additionally have to check end events, as well. --- .../python/xmlization/_generate.py | 42 ++++++++++++------- .../expected_output/xmlization.py | 40 +++++++++++------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/aas_core_codegen/python/xmlization/_generate.py b/aas_core_codegen/python/xmlization/_generate.py index a75bea22d..f115c5dd5 100644 --- a/aas_core_codegen/python/xmlization/_generate.py +++ b/aas_core_codegen/python/xmlization/_generate.py @@ -2289,7 +2289,7 @@ def _raise_if_has_tail_or_attrib( def _read_end_element( {II}element: Element, {II}iterator: Iterator[Tuple[str, Element]] -) -> None: +) -> Element: {I}\"\"\" {I}Read the end element corresponding to the start :paramref:`element` {I}from :paramref:`iterator`. @@ -2315,7 +2315,9 @@ def _read_end_element( {III}f"but got the event {{next_event!r}} and element {{next_element.tag!r}}" {II}) -{I}_raise_if_has_tail_or_attrib(next_element)""" +{I}_raise_if_has_tail_or_attrib(next_element) + +{I}return next_element""" ), Stripped( f"""\ @@ -2339,18 +2341,21 @@ def _read_text_from_element( {I}\"\"\" {I}_raise_if_has_tail_or_attrib(element) -{I}if element.text is None: -{II}raise DeserializationException( -{III}"Expected an element with text, but got an element with no text." -{II}) - {I}text = element.text -{I}_read_end_element( +{I}end_element = _read_end_element( {II}element, -{II}iterator +{II}iterator, {I}) +{I}if text is None: +{II}if end_element.text is None: +{III}raise DeserializationException( +{IIII}"Expected an element with text, but got an element with no text." +{III}) + +{II}text = end_element.text + {I}return text""" ), Stripped( @@ -2496,18 +2501,23 @@ def _read_str_from_element_text( {I}# the ``element`` to contain *some* text. In contrast, this function {I}# can also deal with empty text, in which case it returns an empty string. -{I}_raise_if_has_tail_or_attrib(element) -{I}result = ( -{II}element.text -{II}if element.text is not None -{II}else "" -{I}) +{I}text = element.text -{I}_read_end_element( +{I}end_element = _read_end_element( {II}element, {II}iterator {I}) +{I}if text is None: +{II}text = end_element.text + +{I}_raise_if_has_tail_or_attrib(element) +{I}result = ( +{II}text +{II}if text is not None +{II}else "" +{I}) + {I}return result""" ), Stripped( diff --git a/test_data/python/test_main/aas_core_meta.v3/expected_output/xmlization.py b/test_data/python/test_main/aas_core_meta.v3/expected_output/xmlization.py index 41fb1c29e..71a9e39bb 100644 --- a/test_data/python/test_main/aas_core_meta.v3/expected_output/xmlization.py +++ b/test_data/python/test_main/aas_core_meta.v3/expected_output/xmlization.py @@ -10261,7 +10261,7 @@ def _raise_if_has_tail_or_attrib( def _read_end_element( element: Element, iterator: Iterator[Tuple[str, Element]] -) -> None: +) -> Element: """ Read the end element corresponding to the start :paramref:`element` from :paramref:`iterator`. @@ -10289,6 +10289,8 @@ def _read_end_element( _raise_if_has_tail_or_attrib(next_element) + return next_element + def _read_text_from_element( element: Element, @@ -10310,18 +10312,21 @@ def _read_text_from_element( """ _raise_if_has_tail_or_attrib(element) - if element.text is None: - raise DeserializationException( - "Expected an element with text, but got an element with no text." - ) - text = element.text - _read_end_element( + end_element = _read_end_element( element, - iterator + iterator, ) + if text is None: + if end_element.text is None: + raise DeserializationException( + "Expected an element with text, but got an element with no text." + ) + + text = end_element.text + return text @@ -10461,18 +10466,23 @@ def _read_str_from_element_text( # the ``element`` to contain *some* text. In contrast, this function # can also deal with empty text, in which case it returns an empty string. - _raise_if_has_tail_or_attrib(element) - result = ( - element.text - if element.text is not None - else "" - ) + text = element.text - _read_end_element( + end_element = _read_end_element( element, iterator ) + if text is None: + text = end_element.text + + _raise_if_has_tail_or_attrib(element) + result = ( + text + if text is not None + else "" + ) + return result