Zunächst ein paar Tipps zu deinem Code:
- Namen für Instanzen sollten lowercase sein. `file` ist zudem der Name einer Funktion (bezeichnet dieselbe wie `open`). Nach meiner Erfahrung ist `f` (bei noch-nicht-so-Pythonistas auch `fh` für Filehandle) gängig.
- Anstatt über ``readlines()`` soll man direkt über das Dateiobjekt iterieren, das einen Iterator bereithält und damit speicherschonender arbeitet (weil nicht alles vorgehalten wird). Das sieht dann so aus: `for line in f:`
- Wenn du beim Durchlaufen mitzählen möchtest, kannst du `enumerate` verwenden, dass dir zu jedem Element den aktuellen Index liefert (beginnt bei 0).
- Zudem verwende ich hier die %-Formatierung, die du dir zumindest mal ansehen solltest.
- ``repr()`` sorgt dafür, dass Sonderzeichen wie Tabs oder Zeilenumbrüche als '\t' oder '\n' angezeigt, aber nicht "angewendet" werden. Gerade wenn die Zeile die Bildschirmbreite erreicht, übersieht man schon mal einen Zeilenumbruch.
Zusammengefügt:
Code: Alles auswählen
f = open('Datei.log', 'r')
for num, line in enumerate(f):
print 'Zeile %d: %s' % (num + 1, repr(line))
f.close()
Wenn du außerdem noch Python 2.5 verwendest, kannst du vom neue `with`-Statement Gebrauch machen, wodurch das `f.close()` automatisch ausgeführt wird, auch im Fehlerfall bei ungefangenen Exceptions:
Code: Alles auswählen
from __future__ import with_statement
with open('Datei.log', 'r') as f:
for num, line in enumerate(f):
print 'Zeile %d: %s' % (num + 1, repr(line))
----
Zum Erzeugen des XML lege ich dir ebenfalls ElementTree sehr ans Herz (bei Python ab 2.5 bereits als `xml.etree` mit dabei). Auf der Website findest du Beispiele, wie es zu verwenden ist.
Hier ein Beispiel von mir grob zu deinem Vorhaben. Ich setze voraus, dass du eine exemplarische Liste von 3-Tupeln (date_time, priority, message) hast (du kannst stattdessen natürlich auch Dictionaries oder Objekte verwenden oder das ganze direkt beim Lesen aus der Datei weitergeben).
Erzeugen wir ein paar Testdaten für den Anfang:
Code: Alles auswählen
logs = []
for i in xrange(1, 6):
date_time = '%02d.%02d.20%02d 12:00:%02d' % (i, i, i, i)
logs.append((date_time, i, 'Event #%d has occured.' % i))
for l in logs:
print l
Das sieht dann schon mal so aus:
Code: Alles auswählen
('01.01.2001 12:00:01', 1, 'Event #1 has occured.')
('02.02.2002 12:00:02', 2, 'Event #2 has occured.')
('03.03.2003 12:00:03', 3, 'Event #3 has occured.')
('04.04.2004 12:00:04', 4, 'Event #4 has occured.')
('05.05.2005 12:00:05', 5, 'Event #5 has occured.')
Dann wandeln wir das in XML um und geben es eingerückt aus:
Code: Alles auswählen
from xml.dom.minidom import parseString
from xml.etree.ElementTree import Element, SubElement, tostring
# XML-Baum erzeugen.
root = Element('events')
for date_time, prio, msg in logs:
event_node = SubElement(root, 'event')
SubElement(event_node, 'datetime').text = date_time
SubElement(event_node, 'priority').text = str(prio)
SubElement(event_node, 'message').text = msg
# XML formatiert ausgeben.
xml = tostring(root)
xml_indented = parseString(xml).toprettyxml(' '*4)
print xml_indented
Ausgabe:
Code: Alles auswählen
<?xml version="1.0" ?>
<events>
<event>
<datetime>
01.01.2001 12:00:01
</datetime>
<priority>
1
</priority>
<message>
Event #1 has occured.
</message>
</event>
<event>
<datetime>
02.02.2002 12:00:02
</datetime>
<priority>
2
</priority>
<message>
Event #2 has occured.
</message>
</event>
<event>
<datetime>
03.03.2003 12:00:03
</datetime>
<priority>
3
</priority>
<message>
Event #3 has occured.
</message>
</event>
<event>
<datetime>
04.04.2004 12:00:04
</datetime>
<priority>
4
</priority>
<message>
Event #4 has occured.
</message>
</event>
<event>
<datetime>
05.05.2005 12:00:05
</datetime>
<priority>
5
</priority>
<message>
Event #5 has occured.
</message>
</event>
</events>
Du kannst natürlich auch Daten als Attribute anstatt von Textknoten einfügen, wenn du das für sinnvoller hältst.
Interessant ist ``SubElement(event_node, 'datetime').text = date_time``: Dabei wird eine `SubElement`-Instanz erzeugt, die über den ersten Parameter an den Baum gehängt wird. Diese Instanz bekommt keinen Namen, aber es wird direkt ihr Textknoten über das `text`-Attribut gesetzt. Attribute kannst du dem Konstruktor von `SubElement` mit übergeben, aber wenn du weitere Unterknoten anhängen willst, muss die Instanz einen Namen bekommen, vgl. `event_node`.