pythonjsonxmlxmltodictdicttoxml

How can I convert a Python dictionary to an XML string and back while preserving the structure exactly?


I have a need to convert some json to xml and then back to json ideally preserving the structure. I've gotten quite close but I can't find a way to use dicttoxml/xmltodict to not end up with each list of dictionaries being a dictionary with the key 'item' and the original dictionary it's value.

e.g.

{'mydicts': [{'id': 1, 'name': 'alice'}]}

becomes:

<?xml version="1.0" encoding="UTF-8" ?><root><mydicts><item><id>1</id><name>alice</name></item></mydicts></root>

ends up as:

{'mydicts': [{'item': {'id': '1', 'name': 'alice'}}]}

I had to use force_list as well originally. My last resort will be some post-processing code to make this change but I'd prefer to avoid that. Here is some sample code of what I have now:

import xmltodict
import dicttoxml

original_json = {
    "mydicts": [
        {
            "id": 1,
            "name": "alice"
        }
    ]
}


xml_string = dicttoxml.dicttoxml(original_json, attr_type=False).decode()

new_json = xmltodict.parse(xml_string, xml_attribs=False, force_list={'mydicts'})['root']

print(new_json)

Other solutions are perfectly fine as well.


Solution

  • It works straight forward using xmltodict.unparse() by surrounding the original dict with a root object

    import xmltodict
    
    original_json = {
        "mydicts": [
            {
                "id": 1,
                "name": "alice"
            },
            {
                "id": 2,
                "name": "bob"
            }
        ]
    }
    
    tmp_json = {}
    tmp_json['root'] = original_json
    
    xml_string = xmltodict.unparse(tmp_json)
    
    print(xml_string)
    
    new_json = xmltodict.parse(xml_string, xml_attribs=False)['root']
    
    print(new_json)
    

    Result

    <?xml version="1.0" encoding="utf-8"?>
    <root><mydicts><id>1</id><name>alice</name></mydicts><mydicts><id>2</id><name>bob</name></mydicts></root>
    {'mydicts': [{'id': '1', 'name': 'alice'}, {'id': '2', 'name': 'bob'}]}