Skip to content

Commit 2ba29f6

Browse files
Made changes in the element_to_dict function and changed function names to be more descriptive
1 parent 4a669ee commit 2ba29f6

File tree

2 files changed

+35
-46
lines changed

2 files changed

+35
-46
lines changed

src/modelspec/base_types.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,15 @@ def from_bson(cls, bson_str: str) -> "Base":
170170
def from_xml(cls, xml_str: str) -> "Base":
171171
"""Instantiate a Base object from an XML string"""
172172
from modelspec.utils import (
173-
element_to_dict,
174-
handle_id,
175-
convert_values,
173+
elementtree_element_to_dict,
174+
handle_xml_dict_id,
175+
convert_xml_dict_values,
176176
process_xml_namespace,
177177
)
178178
import re
179179

180180
# When the to_xml() method is used it messes up the string therefore,
181-
# it is necessary to convert it into an elementree object the decode into a string.
181+
# it is necessary to convert it into an elementree object then decode into a string.
182182
xml_string_a = ET.fromstring(xml_str)
183183
xml_string_b = ET.tostring(xml_string_a).decode()
184184

@@ -192,15 +192,15 @@ def from_xml(cls, xml_str: str) -> "Base":
192192
# be removed when converting to a dict, the process_xml_namespaes function does just that.
193193
removed_namespaces = process_xml_namespace(cleaned_xml)
194194

195-
# process_xml_namespace function returns an elementtree object which can be directly worked upon by the element_to_dict
195+
# process_xml_namespace function returns an elementtree object which can be directly worked upon by the elementtree_element_to_dict
196196
# function, this returns a python dictionary
197-
data_dict = element_to_dict(removed_namespaces)
197+
data_dict = elementtree_element_to_dict(removed_namespaces)
198198

199199
# This strips every instance of 'id' from the resulting dictionary structure
200-
removed_id = handle_id(data_dict)
200+
removed_id = handle_xml_dict_id(data_dict)
201201

202202
# XML conversions do not returns exact values, instead all values are returned as a string, this reassigns their actual values
203-
converted_to_actual_val = convert_values(removed_id)
203+
converted_to_actual_val = convert_xml_dict_values(removed_id)
204204

205205
return cls.from_dict(converted_to_actual_val)
206206

@@ -403,9 +403,9 @@ def from_xml_file(cls, filename: str) -> "Base":
403403
A modelspec Base for this XML.
404404
"""
405405
from modelspec.utils import (
406-
element_to_dict,
407-
handle_id,
408-
convert_values,
406+
elementtree_element_to_dict,
407+
handle_xml_dict_id,
408+
convert_xml_dict_values,
409409
process_xml_namespace,
410410
)
411411
import re
@@ -423,17 +423,17 @@ def from_xml_file(cls, filename: str) -> "Base":
423423
cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip()
424424

425425
# Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion
426-
# it passes an element tree object to the element_to_dict function
426+
# it passes an element tree object to the elementtree_element_to_dict function
427427
removed_namespaces = process_xml_namespace(cleaned_xml)
428428

429429
# Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict
430-
data_dict = element_to_dict(removed_namespaces)
430+
data_dict = elementtree_element_to_dict(removed_namespaces)
431431

432432
# Removes every key having 'id' and replaces it with it's value
433-
removed_id = handle_id(data_dict)
433+
removed_id = handle_xml_dict_id(data_dict)
434434

435435
# Values are returned as strings after conversion, this corrects them to their actual values
436-
converted_to_actual_val = convert_values(removed_id)
436+
converted_to_actual_val = convert_xml_dict_values(removed_id)
437437
return cls.from_dict(converted_to_actual_val)
438438

439439
def get_child(self, id: str, type_: str) -> Any:

src/modelspec/utils.py

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -82,22 +82,22 @@ def load_xml(filename: str):
8282
cleaned_xml = re.sub(ns_prefix_pattern, "", xml_string).strip()
8383

8484
# Removes xmlns, xmlns:xsi and xsi:schemaLocation from the xml structure for conversion
85-
# it passes an element tree object to the element_to_dict function
85+
# it passes an element tree object to the elementtree_element_to_dict function
8686
removed_namespaces = process_xml_namespace(cleaned_xml)
8787

8888
# Converts the resulting xml stripped of xmlns, xmlns:xsi and xsi:schemaLocation into a dict
89-
data = element_to_dict(removed_namespaces)
89+
data = elementtree_element_to_dict(removed_namespaces)
9090

9191
# Removes every key having 'id' and replaces it with it's value
92-
removed_id = handle_id(data)
92+
removed_id = handle_xml_dict_id(data)
9393

9494
# Values are returned as strings after conversion, this corrects them to their actual values
95-
converted_to_actual_val = convert_values(removed_id)
95+
converted_to_actual_val = convert_xml_dict_values(removed_id)
9696

97-
return convert_values(converted_to_actual_val)
97+
return convert_xml_dict_values(converted_to_actual_val)
9898

9999

100-
def element_to_dict(element):
100+
def elementtree_element_to_dict(element):
101101
"""
102102
This convert an ElementTree element to a dictionary.
103103
@@ -115,7 +115,7 @@ def element_to_dict(element):
115115
children_by_tag = {}
116116
for child_element in element:
117117
child_key = child_element.tag + "s"
118-
child_value = element_to_dict(child_element)
118+
child_value = elementtree_element_to_dict(child_element)
119119

120120
# Check if the child element has an 'id' attribute
121121
if "id" in child_element.attrib:
@@ -148,21 +148,21 @@ def process_xml_namespace(xml_string):
148148
return root
149149

150150

151-
def handle_id(dictionary):
151+
def handle_xml_dict_id(dictionary):
152152
if isinstance(dictionary, dict):
153153
if "id" in dictionary:
154154
nested_dict = {dictionary["id"]: dictionary.copy()}
155155
del nested_dict[dictionary["id"]]["id"]
156-
return {k: handle_id(v) for k, v in nested_dict.items()}
156+
return {k: handle_xml_dict_id(v) for k, v in nested_dict.items()}
157157
else:
158-
return {k: handle_id(v) for k, v in dictionary.items()}
158+
return {k: handle_xml_dict_id(v) for k, v in dictionary.items()}
159159
elif isinstance(dictionary, list):
160-
return [handle_id(item) for item in dictionary]
160+
return [handle_xml_dict_id(item) for item in dictionary]
161161
else:
162162
return dictionary
163163

164164

165-
def convert_values(value):
165+
def convert_xml_dict_values(value):
166166
"""
167167
This recursively converts values to their actual types.
168168
@@ -186,9 +186,9 @@ def convert_values(value):
186186
elif value.lower() == "none":
187187
return None
188188
elif isinstance(value, dict):
189-
return {key: convert_values(val) for key, val in value.items()}
189+
return {key: convert_xml_dict_values(val) for key, val in value.items()}
190190
elif isinstance(value, list):
191-
return [convert_values(item) for item in value]
191+
return [convert_xml_dict_values(item) for item in value]
192192

193193
return value
194194

@@ -246,47 +246,36 @@ def build_xml_element(data, parent=None):
246246
Returns:
247247
Parent
248248
"""
249-
250249
if parent is None:
251250
parent = ET.Element(data.__class__.__name__)
252251

253252
attrs = attr.fields(data.__class__)
254-
id_attribute_value = None # Store id attribute value to be set after other attributes
255253
for aattr in attrs:
256-
if aattr.name == 'id':
257-
id_attribute_value = data.__getattribute__(aattr.name)
258-
elif isinstance(aattr.default, attr.Factory):
254+
if isinstance(aattr.default, attr.Factory):
259255
children = data.__getattribute__(aattr.name)
260256
if not isinstance(children, (list, tuple)):
261257
children = [children]
262258

263259
for child in children:
264260
child_element = build_xml_element(child)
265261
parent.append(child_element)
266-
267-
# Filters name space and schemaLoacation attributes, only allows non name space attributes to added as attributes
268-
elif not any(
269-
hasattr(data, attr_name)
270-
for attr_name in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]
271-
):
262+
263+
# Filters name space and schemaLoacation attributes, only allows non name space attributes to be added as attributes
264+
elif aattr.name not in ["xmlns", "xmlns_url", "xmlns_loc", "xmln_loc_2"]:
272265
attribute_name = aattr.name
273266
attribute_value = data.__getattribute__(aattr.name)
274267
parent.set(attribute_name, str(attribute_value))
275-
268+
276269
# This defines the various namespaces and schemaLocation of the generated xml
277270
if hasattr(data, "xmlns"):
278271
parent.set("xmlns", data.xmlns)
279272
if hasattr(data, "xmlns_url"):
280273
parent.set("xmlns:xsi", data.xmlns_url)
281274
if hasattr(data, "xmlns_loc"):
282275
parent.set("xsi:schemaLocation", str(data.xmlns_loc + " " + data.xmln_loc_2))
283-
284-
# Set the id attribute after processing all other attributes
285-
if id_attribute_value is not None:
286-
parent.set("id", str(id_attribute_value))
287-
288276
return parent
289277

278+
290279
def ascii_encode_dict(data):
291280
ascii_encode = (
292281
lambda x: x.encode("ascii")

0 commit comments

Comments
 (0)