Frage

ich brauche Doppel Zweige in einer XML-Struktur zu vermeiden erstellen, wenn Sie eine Textdatei Parsing. Sagen wir, die Text-Datei ist wie folgt (die Reihenfolge der Zeilen ist zufällig):

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

So ist der resultierende XML-Baum eine Wurzel mit zwei Zweigen haben sollte. Diese beiden Zweige haben zwei Unterzweige. Der Python-Code Ich benutze diese Textdatei zu analysieren, ist wie folgt:

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

Das Problem mit diesem Code ist, dass ein Zweig in XML-Struktur mit jeder Zeile aus der Text-Datei erstellt wird.

Haben Sie Vorschläge, wie zu vermeiden, eine weitere Niederlassung in XML-Struktur zu schaffen, wenn ein Zweig mit diesem Namen existiert bereits?

War es hilfreich?

Lösung

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)

Die Logik ist einfach - Sie sagten es bereits in Ihrer Frage! Sie müssen lediglich prüfen, ob ein Zweig bereits im Baum existiert es vor der Erstellung.

Beachten Sie, dass dies wahrscheinlich ineffizient ist, da Sie für jede Zeile auf den gesamten Baum suchen nach oben. Dies liegt daran, ElementTree ist nicht für die Einzigartigkeit gestaltet.


Wenn Sie Geschwindigkeit benötigen (was Sie nicht können, vor allem für kleinere Bäume!), Ein effizienter Weg, um eine defaultdict wäre die Verwendung der Baumstruktur zu speichern, bevor es zu einem ElementTree konvertieren.

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)

Andere Tipps

etwas in diese Richtung? Sie halten das Niveau des Zweiges in einem dict wiederverwendet werden.

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]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top