Создание XML-дерева из текстового файла с помощью Python - PullRequest
0 голосов
/ 21 сентября 2010

Мне нужно избегать создания двойных веток в дереве XML при разборе текстового файла. Допустим, текстовый файл выглядит следующим образом (порядок строк случайный):

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

Таким образом, полученное дерево 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, если ветка с таким именем уже существует?

Ответы [ 2 ]

1 голос
/ 21 сентября 2010
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)
0 голосов
/ 21 сентября 2010

что-то в этом роде? Вы сохраняете уровень ветвей для повторного использования в диктовке.

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]
...