creating xml tree from a textfile with Python
Question: I need to avoid creating double branches in an xml tree when parsing a text
file. Let's say the textfile is as follows (the order of lines is random):

branch1:branch11:message11  
branch1:branch12:message12  
branch2:branch21:message21  
branch2:branch22:message22

So the resulting xml tree should have a root with two branches. Both of those
branches have two subbranches. The Python code I use to parse this textfile is
as follows:

    
    
    import string
    fh = open ('xmlbasic.txt', 'r')
    allLines = fh.readlines()
    fh.close()
    import xml.etree.ElementTree as ET
    root = ET.Element('root')
    
    for line in allLines:
       tempv = line.split(':')
       branch1 = ET.SubElement(root, tempv[0])
       branch2 = ET.SubElement(branch1, tempv[1])
       branch2.text = tempv[2]
    
    tree = ET.ElementTree(root)
    tree.write('xmlbasictree.xml')
    

The problem with this code is, that a branch in xml tree is created with each
line from the textfile.

Any suggestions how to avoid creating another branch in xml tree if a branch
with this name exists already?


Answer: 
    with open("xmlbasic.txt") as lines_file:
        lines = lines_file.read()
    
    import xml.etree.ElementTree as ET
    
    root = ET.Element('root')
    
    for line in lines:
        head, subhead, tail = line.split(":")
    
        head_branch = root.find(head)
        if not head_branch:
            head_branch = ET.SubElement(root, head)
    
        subhead_branch = head_branch.find(subhead)
        if not subhead_branch:
            subhead_branch = ET.SubElement(branch1, subhead)
    
        subhead_branch.text = tail
    
    tree = ET.ElementTree(root)
    ET.dump(tree)
    

The logic is simple -- you already stated it in your question! You merely need
to check whether a branch already exists in the tree before creating it.

Note that this is likely inefficient, since you are searching up to the entire
tree for each line. This is because `ElementTree` is not designed for
uniqueness.

* * *

If you require speed (which you may not, especially for smallish trees!), a
more efficient way would be to use a `defaultdict` to store the tree structure
before converting it to an `ElementTree`.

    
    
    import collections
    import xml.etree.ElementTree as ET
    
    with open("xmlbasic.txt") as lines_file:
        lines = lines_file.read()
    
    root_dict = collections.defaultdict( dict )
    for line in lines:
        head, subhead, tail = line.split(":")
        root_dict[head][subhead] = tail
    
    root = ET.Element('root')
    for head, branch in root_dict.items():
        head_element = ET.SubElement(root, head)
        for subhead, tail in branch.items():
            ET.SubElement(head_element,subhead).text = tail
    
    tree = ET.ElementTree(root)
    ET.dump(tree)
    

