Search code examples
pythonxmlpython-3.7minidom

How to iterate through child element using child element


I need to enter the elements of a XML file in a default dictionary. Using first child element as my key, and the other 2 values will be in the list.

I've tried to keep the elements on separate list and then make them pairs, but still no success.

Below is the XML structure

<lines>
    <line>
        <lineName>'Line 1'</lineName>
        <lineCode>'5501'</lineCode>
        <machineName>'Line_1'</machineName>
    </line>
    <line>
        <lineName>'Line 2'</lineName>
        <lineCode>'5502'</lineCode>
        <machineName>'Line_2'</machineName>
    </line>
</lines>

Here's how I'm retrieving elements

item = myxmlcfg.getElementsByTagName('lineName')

item is a list with 2 elements

item['Line 1', 'Line 2']

same will hapen with lineCode and machineName elements

So I need a default dictionary with the output as this

lines {'Line 1': ['5501', 'Line_1'], 'Line 2':['5502', 'Line_2']}

where Key is lineName tag, and value is a list with 2 elements whose values are lineCode and machineName.

Can you suggest me a way to iterate on the xml elements to get an output as above? Any help will be appreciated. Thanks


Solution

  • I don't have any experience with minidom, but with ElementTree it's a trivial task:

    from xml.etree import ElementTree as ET
    from xml.etree.ElementTree import ElementTree
    
    if __name__ == '__main__':
    
        xml_raw = '''
        <lines>
            <line>
                <lineName>'Line 1'</lineName>
                <lineCode>'5501'</lineCode>
                <machineName>'Line_1'</machineName>
            </line>
            <line>
                <lineName>'Line 2'</lineName>
                <lineCode>'5502'</lineCode>
                <machineName>'Line_2'</machineName>
            </line>
        </lines>
        '''
    
        root: ElementTree = ET.fromstring(xml_raw)
        lines = {}
        for line in root.findall('line'):
            name = line.findtext('lineName').strip("'")
            code = line.findtext('lineCode').strip("'")
            machine = line.findtext('machineName').strip("'")
            lines[name] = [code, machine]
        print(lines)
    

    output:

    {'Line 1': ['5501', 'Line_1'], 'Line 2': ['5502', 'Line_2']}