Search code examples
pythonjsonxmlpython-3.xdicttoxml

Convert Json to XML properly


I have following dictionary structure

[{
    "Body" : [{
        "Universal Lift Support" : ["1\"-9\" Extended Length",
                                    "10\"-14.5\" Extended Length",
                                    "15\"-19\" Extended Length",
                                    "20\" + Extended Length"]
    }]

I wanted to use the dicttoxml library to get desired xml-output like:

<root>
    <Body>
        <Universal Lift Support>
            1"-9" Extended Length
            10"-14.5" Extended Length
            15"-19" Extended Length
            20" + Extended Length
        </Universal Lift Support>

However, after applying the next code:

dicttoxml.dicttoxml(result, attr_type=False, root=True)

I got xml-structure like:

<?xml version="1.0" encoding="UTF-8" ?><root><item><Body><item><Universal_Lift_Support><item>1&quot;-9&quot; Extended Length</item><item>10&quot;-14.5&quot; Extended Length</item><item>15&quot;-19&quot; Extended Length</item><item>

What options can help to format and get the output as descibed above?


Solution

  • Consider using built-in Python libraries (json, xml.etree.ElementTree, and to pretty print, xml.dom.minidom) that traverses down json object and builds XML tree. One thing to note: XML nodes cannot contain spaces in names, so it should <UniversalLiftSupport>.

    import json
    import xml.etree.ElementTree as ET
    import xml.dom.minidom
    
    with open('BodyUniversal.json') as f:  
        jsondata = json.load(f)
    
    # INITIALIZING XML DOC AND PARENT TAGS
    root = ET.Element('root')
    body = ET.SubElement(root, 'Body')
    uls = ET.SubElement(body, 'UniversalLiftSupport')
    uls.text = ''
    
    # ITERATE THROUGH LIST, APPENDING TO XML
    for i in jsondata[0]['Body'][0]['Universal Lift Support']:
        uls.text = uls.text + '\n\t\t\t' + i
    
    # OUTPUT AND PRETTY PRINT TREE
    tree_out = ET.tostring(root, encoding="UTF-8")
    newXML = xml.dom.minidom.parseString(tree_out.decode('UTF-8'))
    pretty_xml = newXML.toprettyxml()    
    
    print(pretty_xml)
    # <?xml version="1.0" ?>
    # <root>
    #         <Body>
    #                 <UniversalLiftSupport>
    #                         1&quot;-9&quot; Extended Length
    #                         10&quot;-14.5&quot; Extended Length
    #                         15&quot;-19&quot; Extended Length
    #                         20&quot; + Extended Length</UniversalLiftSupport>
    #         </Body>
    # </root>
    
    # OUTPUT XML CONTENT TO FILE
    with open('Output.xml','w') as f:
        f.write(pretty_xml)