Skip to content

Commit 23a2739

Browse files
modelspec utils file xml serialization added
1 parent 3cc8dc2 commit 23a2739

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

src/modelspec/utils.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import json
33
import bson
44
import yaml
5+
import xml.etree.ElementTree as ET
6+
import xml.dom.minidom
57
import os
68
import math
79
import numpy as np
@@ -54,7 +56,49 @@ def load_bson(filename: str):
5456
data = bson.decode(data_encoded)
5557

5658
return data
59+
5760

61+
def load_xml(filename: str):
62+
"""
63+
Load a generic XML file.
64+
65+
Args:
66+
filename: The name of the XML file to load.
67+
"""
68+
with open(filename, "rb") as infile:
69+
tree = ET.parse(infile) # Parse the XML file into an ElementTree object
70+
root = tree.getroot() # Get the root element
71+
72+
# Convert the ElementTree object to a dictionary
73+
data = element_to_dict(root)
74+
75+
return data
76+
77+
78+
def element_to_dict(element):
79+
"""
80+
Convert an ElementTree element to a dictionary.
81+
82+
Args:
83+
element: The ElementTree element to convert.
84+
85+
Returns:
86+
The converted dictionary.
87+
"""
88+
if len(element) == 0:
89+
return element.text
90+
91+
result = {}
92+
for child in element:
93+
child_data = element_to_dict(child)
94+
if child.tag in result:
95+
if not isinstance(result[child.tag], list):
96+
result[child.tag] = [result[child.tag]]
97+
result[child.tag].append(child_data)
98+
else:
99+
result[child.tag] = child_data
100+
101+
return result
58102

59103
def save_to_json_file(info_dict, filename, indent=4):
60104

@@ -72,6 +116,72 @@ def save_to_yaml_file(info_dict, filename, indent=4):
72116
with open(filename, "w") as fp:
73117
fp.write(stry)
74118

119+
def save_to_xml_file(info_dict, filename, indent=4):
120+
"""
121+
Save a dictionary to an XML file.
122+
123+
Args:
124+
info_dict (dict): The dictionary containing the data to be saved.
125+
filename (str): The name of the file to save the XML data to.
126+
indent (int, optional): The number of spaces used for indentation in the XML file.
127+
Defaults to 4.
128+
"""
129+
root = ET.Element("root")
130+
131+
build_xml_element(root, info_dict)
132+
133+
# Create an ElementTree object with the root element
134+
tree = ET.ElementTree(root)
135+
136+
# Generate the XML string
137+
xml_str = ET.tostring(root, encoding="utf-8").decode("utf-8")
138+
139+
# Create a pretty-formatted XML string using minidom
140+
dom = xml.dom.minidom.parseString(xml_str)
141+
pretty_xml_str = dom.toprettyxml(indent=" " * indent)
142+
143+
# Write the XML data to the file
144+
with open(filename, "w", encoding="utf-8") as file:
145+
file.write(pretty_xml_str)
146+
147+
def build_xml_element(parent, data):
148+
if isinstance(data, dict):
149+
for key, value in data.items():
150+
if isinstance(value, dict):
151+
element = ET.SubElement(parent, key)
152+
build_xml_element(element, value)
153+
elif isinstance(value, list):
154+
for item in value:
155+
subelement = ET.SubElement(parent, key)
156+
build_xml_element(subelement, item)
157+
else:
158+
element = ET.SubElement(parent, key)
159+
element.text = str(value)
160+
else:
161+
parent.text = str(data)
162+
163+
def _parse_xml_element(element):
164+
"""
165+
Recursively convert an XML element to a dictionary.
166+
167+
Args:
168+
element: The XML element.
169+
170+
Returns:
171+
A dictionary representing the XML element and its children.
172+
"""
173+
data = {}
174+
for child in element:
175+
if child.tag not in data:
176+
data[child.tag] = []
177+
if len(child) > 0:
178+
data[child.tag].append(_parse_xml_element(child))
179+
else:
180+
data[child.tag].append(child.text)
181+
for key, value in data.items():
182+
if len(value) == 1:
183+
data[key] = value[0]
184+
return data
75185

76186
def ascii_encode_dict(data):
77187
ascii_encode = (

0 commit comments

Comments
 (0)