From 6e3f505bf9ed57d6209dad5afc4a7bdf90bc5fe8 Mon Sep 17 00:00:00 2001 From: Leo Bergolth Date: Sat, 9 Nov 2024 16:14:40 +0100 Subject: [PATCH] Move root clazz lookup to a separate method (#1090) * move root clazz lookup to a separate method in order to be able to extend it by subclassing * use google style docstrings --------- Co-authored-by: Alexander 'Leo' Bergolth --- xsdata/formats/dataclass/parsers/bases.py | 45 +++++++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/xsdata/formats/dataclass/parsers/bases.py b/xsdata/formats/dataclass/parsers/bases.py index 9bd4cd68c..d0a3f4347 100644 --- a/xsdata/formats/dataclass/parsers/bases.py +++ b/xsdata/formats/dataclass/parsers/bases.py @@ -96,14 +96,13 @@ def start( except IndexError: xsi_type = ParserUtils.xsi_type(attrs, ns_map) - # Match element qname directly - if clazz is None: - clazz = self.context.find_type(qname) - - # Root is xs:anyType try xsi:type - if clazz is None and xsi_type: - clazz = self.context.find_type(xsi_type) - + clazz = self.find_root_clazz( + clazz=clazz, + qname=qname, + attrs=attrs, + ns_map=ns_map, + xsi_type=xsi_type, + ) # Exit if we still have no binding model if clazz is None: raise ParserError(f"No class found matching root: {qname}") @@ -153,6 +152,36 @@ def end( item = queue.pop() return item.bind(qname, text, tail, objects) + def find_root_clazz( + self, + clazz: Optional[Type], + qname: str, + attrs: Dict, + ns_map: Dict, + xsi_type: Optional[str], + ) -> Optional[Type]: + """ + Obtain the root clazz, maybe from the provided clazz. + + Args: + clazz: The root class type, auto locate if omitted + qname: Qualified name + attrs: Attribute key-value map + ns_map: Namespace prefix-URI map + xsi_type: The xsi:type of the object + Returns: + The root class. + """ + # Match element qname directly + if clazz is None: + clazz = self.context.find_type(qname) + + # Root is xs:anyType try xsi:type + if clazz is None and xsi_type: + clazz = self.context.find_type(xsi_type) + + return clazz + @dataclass class RecordParser(NodeParser):