Skip to content

Instantly share code, notes, and snippets.

@MichaelJRussell
Created January 27, 2024 19:05
Show Gist options
  • Save MichaelJRussell/316936cf8ae9ed7ee25cab7ec8fe6a28 to your computer and use it in GitHub Desktop.
Save MichaelJRussell/316936cf8ae9ed7ee25cab7ec8fe6a28 to your computer and use it in GitHub Desktop.
Python script to convert a JSON list of objects to XML
import json
from xml.sax.saxutils import escape
from xml.etree.ElementTree import Element, tostring
from xml.dom.minidom import parseString
import logging
from lxml import etree
logger = logging.getLogger(__name__)
class XmlConverter:
def __init__(self) -> None:
pass
def convert(self, json_string: str) -> str:
json_data = json.loads(json_string)
# The data will be an array of cases; if the array is empty, do not proceed
if len(json_data) == 0:
return None
xml_str = self.__json_to_xml__(json_data)
if not self.__is_valid_xml__(xml_str):
return None
return xml_str
def __json_to_xml__(self, json_data) -> str:
"""
Convert JSON data to an XML string.
"""
root_name = 'Cases'
xml_element = self.__cases_to_xml__(json_data, root_name)
return parseString(tostring(xml_element)).toprettyxml()
def __cases_to_xml__(self, case_list: list[dict[str, any]], root_name: str) -> Element:
root = Element(root_name)
for entry in case_list:
case_child = Element('LabResults')
root.append(self.__dict_to_xml__(entry['labResults'], case_child))
return root
def __dict_to_xml__(self, d: dict[str, any], root: Element) -> Element:
"""
Convert a dictionary to an XML Element.
"""
for key, value in d.items():
key_capital = key[:1].upper() + key[1:]
if key == 'receivedDate':
key_capital = key
child = Element(key_capital)
if isinstance(value, dict):
root.append(self.__dict_to_xml__(value, child))
elif isinstance(value, list):
# Containing name will be pluralized, make child name singular
key_capital = key_capital[:-1]
for item in value:
list_root = Element(key_capital)
child.append(self.__dict_to_xml__(item, list_root))
root.append(child)
else:
child.text = escape(str(value))
if child.text.lower().startswith('not d'):
child.text = 'Not Detected'
root.append(child)
return root
def __is_valid_xml__(self, xml_string):
try:
etree.fromstring(xml_string)
return True
except etree.XMLSyntaxError as e:
print('XML Error:', e)
logger.warning('Invalid XML encountered', exc_info=e)
return False
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment