Source code for ts_lib_xml.xml_to_dict

"""The functions in this module are based on this snippet: https://stackoverflow.com/a/10077069
They follow the XML-to-JSON specification described here: https://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html
"""

from collections import defaultdict
from xml.etree.ElementTree import Element

from defusedxml import ElementTree as etree


def _etree_to_dict(element: Element) -> dict:
    """Convert an ElementTree element to a dictionary."""

    children = list(element)
    element_dict = {element.tag: {} if element.attrib else None}

    if children:
        child_elements = defaultdict(list)
        for child_dict in map(_etree_to_dict, children):
            for key, value in child_dict.items():
                child_elements[key].append(value)
        element_dict = {
            element.tag: {
                key: value[0] if len(value) == 1 else value
                for key, value in child_elements.items()
            }
        }
    if element.attrib:
        element_dict[element.tag].update(
            ("@" + key, value) for key, value in element.attrib.items()
        )
    if element.text:
        text = element.text.strip()
        if children or element.attrib:
            if text:
                element_dict[element.tag]["#text"] = text
        else:
            element_dict[element.tag] = text
    return element_dict


[docs] def xml_string_to_dict(xml_string: str) -> dict: """Convert an XML string to a dictionary.""" root = etree.XML(xml_string) return _etree_to_dict(root)