Converting an array dict to xml in python?

前端 未结 3 1223
轮回少年
轮回少年 2021-02-13 18:53

I have this array that I need to convert to xml.

array = [
    {
        \'time\': {\"hour\":\"1\", \"minute\":\"30\",\"seconds\": \"40\"}
    },
    {
        \         


        
相关标签:
3条回答
  • 2021-02-13 18:58

    For simple cases, you can go with something like this:

    def object_to_xml(data: Union[dict, bool], root='object'):
        xml = f'<{root}>'
        if isinstance(data, dict):
            for key, value in data.items():
                xml += object_to_xml(value, key)
    
        elif isinstance(data, (list, tuple, set)):
            for item in data:
                xml += object_to_xml(item, 'item')
    
        else:
            xml += str(data)
    
        xml += f'</{root}>'
        return xml
    

    Examples:

    xml = object_to_xml([1, 2, 3], 'root')
    # <root><item>1</item><item>2</item><item>3</item></root>
    
    xml = object_to_xml({"name": "the matrix", "age": 20, "metadata": {"dateWatched": datetime.datetime.now()}}, 'movie')
    # <movie><name>the matrix</name><age>20</age><metadata><dateWatched>2020-11-01 00:35:39.020358</dateWatched></metadata></movie>
    
    0 讨论(0)
  • 2021-02-13 19:17

    I ended up taking the solution from here, then adding a for-loop over the elements in your array. The output uses attributes instead of elements like you had asked, though.

    Full code outside of that function is this. I ended up using regex to strip out the intermediate <test></test> tags, then placed the on the outside at the end.

    import re 
    
    array = [
        {
            'time': {"hour":"1", "minute":"30","seconds": "40"}
        },
        {
            'place': {"street":"40 something", "zip": "00000"}
        }
    ]
    
    xml_title = "test"
    xml_tag_pattern = re.compile(r'</?{}>'.format(xml_title))
    inner_xml = re.sub(xml_tag_pattern, '', ''.join(dict2xml(e, root_node=tag_name) for e in array))
    
    print('<{0}>{1}</{0}>'.format(xml_title, inner_xml))
    

    The output is this (new lines added for clarity)

    <test>
        <time hour="1" seconds="40" minute="30"/>
        <place street="40 something" zip="00000"/>
    </test>
    
    0 讨论(0)
  • 2021-02-13 19:18

    As noted in the comments, your original question mixes attributes and elements. If you want everything as elements, you might be able to use dicttoxml. For example:

    from dicttoxml import dicttoxml
    
    array = [
        {
            'time': {"hour":"1", "minute":"30","seconds": "40"}
        },
        {
            'place': {"street":"40 something", "zip": "00000"}
        }
    ]
    
    xml = dicttoxml(array, custom_root='test', attr_type=False)
    

    Produces the following XML:

    <?xml version="1.0" encoding="UTF-8" ?>
    <test>
        <item>
            <time>
                <seconds>40</seconds>
                <minute>30</minute>
                <hour>1</hour>
            </time>
        </item>
        <item>
            <place>
                <street>40 something</street>
                <zip>00000</zip>
            </place>
        </item>
    </test>
    

    If you can convert your dictionary to:

    dictionary = {
        'time': {"hour":"1", "minute":"30","seconds": "40"},
        'place': {"street":"40 something", "zip": "00000"}
    }
    

    Then your XML will look as desired.

    <?xml version="1.0" encoding="UTF-8" ?>
    <test>
        <place>
            <street>40 something</street>
            <zip>00000</zip>
        </place>
        <time>
            <seconds>40</seconds>
            <minute>30</minute>
            <hour>1</hour>
        </time>
    </test>
    

    Note that, in general, the order of dictionary keys are not guaranteed, so if you want to preserve the order of keys in a dict, you may want to check out collections.OrderedDict.

    0 讨论(0)
提交回复
热议问题