【问题标题】:creating xml tree from a textfile with Python使用 Python 从文本文件创建 xml 树
【发布时间】:2010-09-21 10:03:30
【问题描述】:

在解析文本文件时,我需要避免在 xml 树中创建双分支。假设文本文件如下(行的顺序是随机的):

branch1:branch11:message11
分支 1:分支 12:消息 12
分支 2:分支 21:消息 21
分支2:分支22:消息22

所以生成的 xml 树应该有一个有两个分支的根。这两个分支都有两个子分支。我用来解析这个文本文件的 Python 代码如下:

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')

这段代码的问题是,xml树中的一个分支是用文本文件中的每一行创建的。

如果已经存在同名的分支,有什么建议可以避免在 xml 树中创建另一个分支?

【问题讨论】:

    标签: python xml elementtree


    【解决方案1】:
    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)
    

    逻辑很简单——您已经在问题中说明了!您只需要在创建之前检查树中是否已经存在分支。

    请注意,这可能效率低下,因为您要搜索整棵树的每一行。这是因为ElementTree 不是为唯一性而设计的。


    如果您需要速度(您可能不需要,尤其是对于小树!),更有效的方法是使用 defaultdict 来存储树结构,然后再将其转换为 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)
    

    【讨论】:

    • 谢谢,这个和其他答案都可以正常工作,但我会坚持使用 defaultdict,因为实际上文本和 xml 文件相当大。
    【解决方案2】:

    类似的东西?您保留分支的级别以在 dict 中重复使用。

    b1map = {}
    
    for line in allLines:
       tempv = line.split(':')
       branch1 = b1map.get(tempv[0])
       if branch1 is None:
           branch1 = b1map[tempv[0]] = ET.SubElement(root, tempv[0])
       branch2 = ET.SubElement(branch1, tempv[1])
       branch2.text = tempv[2]
    

    【讨论】:

      猜你喜欢
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      相关资源
      最近更新 更多