Created
January 27, 2024 19:05
-
-
Save MichaelJRussell/316936cf8ae9ed7ee25cab7ec8fe6a28 to your computer and use it in GitHub Desktop.
Python script to convert a JSON list of objects to XML
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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