Skip to content

Commit 3cc8dc2

Browse files
modelspec basefile
1 parent 40185ef commit 3cc8dc2

File tree

1 file changed

+108
-1
lines changed

1 file changed

+108
-1
lines changed

src/modelspec/base_types.py

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import json
22
import yaml
33
import bson
4+
import xml.etree.ElementTree as ET
5+
import xml.dom.minidom
46
import sys
57

68
import numpy as np
@@ -113,6 +115,25 @@ def to_bson(self) -> str:
113115
"""
114116
return bson.encode(self.to_dict())
115117

118+
def to_xml(self) -> str:
119+
"""
120+
Convert the data dictionary to an XML string representation using the ElementTree library.
121+
"""
122+
from modelspec.utils import build_xml_element
123+
root = ET.Element("root")
124+
build_xml_element(root, self.to_dict())
125+
126+
xml_string = ET.tostring(
127+
root,
128+
encoding='utf-8',
129+
xml_declaration=False,
130+
method='xml'
131+
).decode('utf-8')
132+
133+
parsed_xml = xml.dom.minidom.parseString(xml_string)
134+
pretty_xml = parsed_xml.toprettyxml(indent=" " * 4)
135+
return pretty_xml
136+
116137
@classmethod
117138
def from_dict(cls, d: Dict[str, Any]) -> "Base":
118139
"""Instantiate an Base object from a dictionary"""
@@ -144,6 +165,15 @@ def from_bson(cls, bson_str: str) -> "Base":
144165
"""Instantiate an modelspec object from a BSON string"""
145166
return cls.from_dict(bson.decode(bson_str))
146167

168+
@classmethod
169+
def from_xml(cls, xml_str: str) -> "Base":
170+
"""Instantiate a Base object from an XML string"""
171+
from modelspec.utils import _parse_xml_element
172+
173+
root = ET.fromstring(xml_str)
174+
data_dict = _parse_xml_element(root)
175+
return cls.from_dict(data_dict)
176+
147177
def to_json_file(
148178
self, filename: Optional[str] = None, include_metadata: bool = True
149179
) -> str:
@@ -189,7 +219,7 @@ def to_bson_file(self, filename: str, include_metadata: bool = True) -> str:
189219
)
190220
outfile.write(bson_data)
191221

192-
return filename
222+
return filename
193223

194224
def to_yaml(self, include_metadata: bool = True) -> str:
195225
"""
@@ -232,6 +262,61 @@ def to_yaml_file(
232262
)
233263

234264
return filename
265+
266+
267+
268+
def to_xml_file(self, filename: Optional[str] = None, include_metadata: bool = True) -> str:
269+
from modelspec.utils import build_xml_element
270+
271+
if filename is None:
272+
filename = f"{self.id}.xml"
273+
274+
root = ET.Element("root") # Create the root element
275+
276+
build_xml_element(root, self.to_dict())
277+
278+
# Create an ElementTree object with the root element
279+
tree = ET.ElementTree(root)
280+
281+
# Generate the XML string
282+
xml_str = ET.tostring(root, encoding="utf-8").decode("utf-8")
283+
284+
# Pretty format the XML string using minidom
285+
#dom = xml.dom.minidom.parseString(xml_str)
286+
#pretty_xml_str = dom.toprettyxml(indent=" ")
287+
288+
# Write the formatted XML data to the file
289+
with open(filename, "w", encoding="utf-8") as file:
290+
file.write(xml_str)
291+
292+
return filename
293+
294+
295+
296+
# def to_xml_file(self, filename: Optional[str] = None, include_metadata: bool = True) -> str:
297+
# from modelspec.utils import build_xml_element
298+
# if filename is None:
299+
# filename = f"{self.id}.xml"
300+
301+
# root = ET.Element("root") # Create the root element
302+
303+
# # Convert self to dictionary representation (assuming self.to_dict() returns a dictionary)
304+
# model_dict = self.to_dict()
305+
306+
# # Create XML elements based on the dictionary
307+
# build_xml_element(root, model_dict)
308+
309+
# xml_data = ET.tostring(root, encoding="utf-8", xml_declaration=True)
310+
311+
# # Create a pretty-formatted XML string using minidom
312+
# xml_dom = xml.dom.minidom.parseString(xml_data)
313+
# pretty_xml_str = xml_dom.toprettyxml(indent=" ")
314+
315+
# with open(filename, "w") as file:
316+
# file.write(pretty_xml_str)
317+
318+
# return filename
319+
235320

236321
@classmethod
237322
def from_file(cls, filename: str) -> "Base":
@@ -251,6 +336,8 @@ def from_file(cls, filename: str) -> "Base":
251336
return cls.from_json_file(filename)
252337
elif filename.endswith(".bson"):
253338
return cls.from_bson_file(filename)
339+
elif filename.endswith(".xml"):
340+
return cls.from_xml_file(filename)
254341
else:
255342
raise ValueError(
256343
f"Cannot auto-detect modelspec serialization format from filename ({filename}). The filename "
@@ -303,6 +390,26 @@ def from_yaml_file(cls, filename: str) -> "Base":
303390
d = yaml.safe_load(infile)
304391
d = yaml_converter.structure(d, Dict)
305392
return cls.from_dict(d)
393+
394+
@classmethod
395+
def from_xml_file(cls, filename: str) -> "Base":
396+
"""
397+
Create a Base from its XML representation stored in a file.
398+
399+
Args:
400+
filename: The file from which to load the XML data.
401+
402+
Returns:
403+
A modelspec Base for this XML.
404+
"""
405+
from modelspec.utils import _parse_xml_element
406+
407+
with open(filename) as infile:
408+
tree = ET.parse(filename)
409+
root = tree.getroot()
410+
411+
data_dict = _parse_xml_element(root)
412+
return cls.from_dict(data_dict)
306413

307414
def get_child(self, id: str, type_: str) -> Any:
308415
"""

0 commit comments

Comments
 (0)