Ein Computerprogramm läuft ausschließlich im Arbeitsspeicher. Das ist ein schneller, aber vergänglicher Ort um Daten abzulegen. Möchte man
braucht es weiterer Technologien, um die Daten aus dem Arbeitsspeicher z.B. auf die Festplatte oder in eine Datenbank zu speichern bzw. von dort wieder einzulesen.
Der Überbegriff für jegliches Speichern von Daten in einer Datei ist Serialisierung. Die Daten des Programmes werden hierbei kodiert und als lineare Sequenz von Bits&Bytes abgelegt. Im folgenden werden einige solcher Formate vorgestellt und kurz erklärt, wie sie mit Python gelesen bzw. geschrieben werden können.
Python Pickles sind Python's interne Art, Daten eines Objektes zu speichern. Der Vorteil ist, dass es sehr schnell und speicherplatsparend funktioniert. Die Nachteile sind, dass dies eine rein Python spezifische Lösung ist und zum Laden des pickles wird genau die richtige Klasse (mit derselben Struktur) benötigt.
from os.path import join
try:
import cPickle as pickle
finally:
import pickle
class Data(object):
def __init__(self, a, b):
self.a = a
self.b = b
d1 = Data(a = "this is value a", b = [2, 2, 31])
print(id(d1))
19539152
Es ist immer eine gute Idee, das Protokoll auf die aktuellste Version zu stellen. Standardmäßig wird immer die niedrigste (und viel schlechtere) Variante genommen, um rückwärskompatibel zu sein.
pickle_fn = join("res", "data.pickle")
with open(pickle_fn, "wb") as pickle_file:
pickle.dump(d1, pickle_file, protocol=pickle.HIGHEST_PROTOCOL)
Nun wird die Klasse wieder geladen, in d2
statt d1
, und gelesen.
Man sieht, die Klasse ist rekonstruiert worden, die Daten sind verfügbar, und die Speicheradresse ist eine andere.
d2 = pickle.load(open(pickle_fn))
print(type(d2), id(d2))
d2.a, d2.b
(<class '__main__.Data'>, 20652112)
('this is value a', [2, 2, 31])
Dies ist ein sehr einfaches, rein textbasiertes Format.
Es handelt sich um spatenweise angeordnete Daten in Form einer Tabelle,
wobei Spaten durch ",
" oder ";
" getrennt werden.
Die erste Zeile ist üblicherweise eine Beschriftung der Spalten,
darunter ein Eintrag pro Zeile.
Strings werden üblicherweise in Anführungszeichen gestellt,
insbesondere um Verwechslungen mit dem trennenden Zeichen zu vermeiden.
Achtung, es gibt keine Typeninformation!
flugzeit_csv= join("res", "flugzeit.csv")
%%writefile $flugzeit_csv
origin,destination,time,distance
VIE,LHR,2:30,1100
VIE,JFK,8:59,6823
JFK,ZCL,4:39,3346
SFO,JFK,5:30,4162
PEK,ZRH,10:55,7993
HNL,YOW,10:08,7758
VIE,BER,1:09,676
CDG,TIP,3:01,2019
CDG,ATZ,4:47,3453
CDG,FCO,1:52,1102
VIE,FCO,1:28,780
LIS,AMM,5:39,4138
LIS,BER,3:22,2307
LIS,WAW,3:55,2754
PEK,SVO,7:43,5811
BRN,HUU,13:20,10331
Overwriting res/flugzeit.csv
import csv
for line in csv.reader(open(flugzeit_csv), delimiter=","):
print line
['origin', 'destination', 'time', 'distance'] ['VIE', 'LHR', '2:30', '1100'] ['VIE', 'JFK', '8:59', '6823'] ['JFK', 'ZCL', '4:39', '3346'] ['SFO', 'JFK', '5:30', '4162'] ['PEK', 'ZRH', '10:55', '7993'] ['HNL', 'YOW', '10:08', '7758'] ['VIE', 'BER', '1:09', '676'] ['CDG', 'TIP', '3:01', '2019'] ['CDG', 'ATZ', '4:47', '3453'] ['CDG', 'FCO', '1:52', '1102'] ['VIE', 'FCO', '1:28', '780'] ['LIS', 'AMM', '5:39', '4138'] ['LIS', 'BER', '3:22', '2307'] ['LIS', 'WAW', '3:55', '2754'] ['PEK', 'SVO', '7:43', '5811'] ['BRN', 'HUU', '13:20', '10331']
Wie man sieht, Python's csv
modul hat die Datei mühelos lesen können.
Einzig das Trennzeichen musste gesetzt werden.
Alle Einträge sind jedoch Strings.
Die Zahlen müssten für eine weitere Verarbeitung umgewandelt werden.
Pandas kann DatenFrames von CSV Tabellen einlesen. Dabei werden die Datentypen (wenn möglich) automatisch konvertiert und es lassen sich Header und Indices genauer angeben.
In diesem gegebenen Fall wird wieder der Strichpunkt als Trennzeichen angegeben und keiner der Spalten als Index definiert.
import pandas as pd
flighttimes = pd.DataFrame.from_csv(flugzeit_csv, sep=",", index_col=None)
flighttimes
origin | destination | time | distance | |
---|---|---|---|---|
0 | VIE | LHR | 2:30 | 1100 |
1 | VIE | JFK | 8:59 | 6823 |
2 | JFK | ZCL | 4:39 | 3346 |
3 | SFO | JFK | 5:30 | 4162 |
4 | PEK | ZRH | 10:55 | 7993 |
5 | HNL | YOW | 10:08 | 7758 |
6 | VIE | BER | 1:09 | 676 |
7 | CDG | TIP | 3:01 | 2019 |
8 | CDG | ATZ | 4:47 | 3453 |
9 | CDG | FCO | 1:52 | 1102 |
10 | VIE | FCO | 1:28 | 780 |
11 | LIS | AMM | 5:39 | 4138 |
12 | LIS | BER | 3:22 | 2307 |
13 | LIS | WAW | 3:55 | 2754 |
14 | PEK | SVO | 7:43 | 5811 |
15 | BRN | HUU | 13:20 | 10331 |
Die time
Spalte wird nun explizit in Stunden konvertiert und als neue Spalte time2
geführt.
def hm_time(entry):
h, m = entry.split(":")
return int(h) + int(m) / 60.
flighttimes["time2"] = flighttimes.time.apply(hm_time)
flighttimes
origin | destination | time | distance | time2 | |
---|---|---|---|---|---|
0 | VIE | LHR | 2:30 | 1100 | 2.500000 |
1 | VIE | JFK | 8:59 | 6823 | 8.983333 |
2 | JFK | ZCL | 4:39 | 3346 | 4.650000 |
3 | SFO | JFK | 5:30 | 4162 | 5.500000 |
4 | PEK | ZRH | 10:55 | 7993 | 10.916667 |
5 | HNL | YOW | 10:08 | 7758 | 10.133333 |
6 | VIE | BER | 1:09 | 676 | 1.150000 |
7 | CDG | TIP | 3:01 | 2019 | 3.016667 |
8 | CDG | ATZ | 4:47 | 3453 | 4.783333 |
9 | CDG | FCO | 1:52 | 1102 | 1.866667 |
10 | VIE | FCO | 1:28 | 780 | 1.466667 |
11 | LIS | AMM | 5:39 | 4138 | 5.650000 |
12 | LIS | BER | 3:22 | 2307 | 3.366667 |
13 | LIS | WAW | 3:55 | 2754 | 3.916667 |
14 | PEK | SVO | 7:43 | 5811 | 7.716667 |
15 | BRN | HUU | 13:20 | 10331 | 13.333333 |
# maximum overall distance
flighttimes.ix[flighttimes.distance.argmax()]
origin BRN destination HUU time 13:20 distance 10331 time2 13.33333 Name: 15, dtype: object
# maximum distance, for each origin
for group, subdf in flighttimes.groupby("origin"):
m = flighttimes.ix[subdf.distance.argmax()]
print("Maximum distance from %s: %5d km to %s" % (group, m.distance, m.destination))
Maximum distance from BRN: 10331 km to HUU Maximum distance from CDG: 3453 km to ATZ Maximum distance from HNL: 7758 km to YOW Maximum distance from JFK: 3346 km to ZCL Maximum distance from LIS: 4138 km to AMM Maximum distance from PEK: 7993 km to ZRH Maximum distance from SFO: 4162 km to JFK Maximum distance from VIE: 6823 km to JFK
Zur Auflockerung eine grafische Darstellung der Weg-Zeit Abhängigkeit. Wenig Überraschend, es ist direkt proportional!
%matplotlib inline
import matplotlib
matplotlib.rcParams["figure.figsize"] = (12,7)
# plot of distance vs. converted time in hours. easy for pandas dataframes!
flighttimes.plot(x = "distance", y = "time2", kind="scatter", ylim=0, xlim=0)
<matplotlib.axes._subplots.AxesSubplot at 0x341f8d0>
Für größere Datenmengen bzw. im professionellen/wissenschaftlichen Umfeld werden Datenbanken eingesetzt. Die Daten werden in einem für die Datenbank spezifische Art gespeichert (sind also nicht wie CSV Dateien von beliebigen Programmen lesbar), beinhalten aber zusätzlich Informationen zu den Typen jeder Spalte. Datenbanken bieten eingebaute Hilfsmittel wie Suchindizes und eine Abfragesprache, es können mehrere Tabellen auf verschiedenste Arten verknüpft werden, und die Verarbeitungsgeschwindigkeit ist viel höher.
Eingebaut in Python ist sqlite3
.
Das folgende Beispiel speichert die Daten der CSV Datei in einer sqlite3 Datenbank und macht eine Abfrage.
db_filename = join("res", "flugzeit.db")
import os
if os.path.exists(db_filename):
os.unlink(db_filename)
import sqlite3
conn = sqlite3.connect(db_filename)
# for the connection `conn`, get a cursor and operate on the table
curs = conn.cursor
curs = conn.cursor()
curs.execute('''
CREATE TABLE flugzeit
(origin text, destination text, distance real, time real)
''')
<sqlite3.Cursor at 0x34191f0>
for idx, (orig, dest, _, dist, time2) in flighttimes.iterrows():
curs.execute("INSERT INTO flugzeit VALUES(?, ?, ?, ?)", (orig, dest, dist, time2))
"{:>7}".format("asdf")
' asdf'
# Hilfsfunktion: gibt die Abfrage Zeilenweise aus
def show_query(query):
for row in query:
out = []
for entry in row:
if isinstance(entry, float): out.append("{:>9.2f}".format(entry))
elif isinstance(entry, int): out.append("{:>9d}".format(entry))
else: out.append("{:>7s}".format(entry))
print(" ".join(out))
show_query(curs.execute("SELECT * FROM flugzeit"))
VIE LHR 1100.00 2.50 VIE JFK 6823.00 8.98 JFK ZCL 3346.00 4.65 SFO JFK 4162.00 5.50 PEK ZRH 7993.00 10.92 HNL YOW 7758.00 10.13 VIE BER 676.00 1.15 CDG TIP 2019.00 3.02 CDG ATZ 3453.00 4.78 CDG FCO 1102.00 1.87 VIE FCO 780.00 1.47 LIS AMM 4138.00 5.65 LIS BER 2307.00 3.37 LIS WAW 2754.00 3.92 PEK SVO 5811.00 7.72 BRN HUU 10331.00 13.33
# sort by decreasing distance
show_query(curs.execute("SELECT * FROM flugzeit ORDER BY -distance"))
BRN HUU 10331.00 13.33 PEK ZRH 7993.00 10.92 HNL YOW 7758.00 10.13 VIE JFK 6823.00 8.98 PEK SVO 5811.00 7.72 SFO JFK 4162.00 5.50 LIS AMM 4138.00 5.65 CDG ATZ 3453.00 4.78 JFK ZCL 3346.00 4.65 LIS WAW 2754.00 3.92 LIS BER 2307.00 3.37 CDG TIP 2019.00 3.02 CDG FCO 1102.00 1.87 VIE LHR 1100.00 2.50 VIE FCO 780.00 1.47 VIE BER 676.00 1.15
# minimum time from each origin
show_query(curs.execute("""
SELECT origin, destination, min(time)
FROM flugzeit
GROUP BY origin
"""))
BRN HUU 13.33 CDG FCO 1.87 HNL YOW 10.13 JFK ZCL 4.65 LIS WAW 3.37 PEK SVO 7.72 SFO JFK 5.50 VIE FCO 1.15
# maximum distance from LIS
curs.execute("""
SELECT *
FROM flugzeit
WHERE origin = 'LIS' AND
distance = (SELECT max(distance) FROM flugzeit WHERE origin = 'LIS')
""").fetchone()
(u'LIS', u'AMM', 4138.0, 5.65)
JSON ist eine der modernen und am weitesten verbreiteten Serialisierungssprachen. Es handelt sich um eine von JavaScript abgeleiteten Datenstruktur, welche nicht nur von vielen Programmiersprachen verstanden wird, sondern auch auf einfache Art komplex verschachtelte Datenstrukturen speichern kann. JSON (und ähnliche Serialisierungsformate) sind als einzelner großer String zu verstehen, welche mit mehreren Syntaxzeichen (eckige Klammer, geschwungene Klammer, Doppelpunkt, ...) die Struktur definieren.
Python liefert hierfür das json (json in python 3) mit.
Wir bleiben bei dem Beispiel der Flugdistanzen und Konvertieren die Pandas Daten zu JSON -- in diesem Fall als Liste von assoziativen Dictionaries.
flighttimes_py = []
for _, data in flighttimes.iterrows():
entry = {"orig" : data.origin,
"dest" : data.destination,
"dist" : data.distance,
"hours": data.time2 }
flighttimes_py.append(entry)
Konvertierung der Python Datenstruktur (welche schon so gut wie JSON ist!) zu JSON.
indent=2
ist nicht notwendig, liefert aber die hübsche Einrückung.
import json
flighttimes_json = json.dumps(flighttimes_py, indent=2)
print(flighttimes_json)
[ { "dest": "LHR", "hours": 2.5, "dist": 1100, "orig": "VIE" }, { "dest": "JFK", "hours": 8.983333333333333, "dist": 6823, "orig": "VIE" }, { "dest": "ZCL", "hours": 4.65, "dist": 3346, "orig": "JFK" }, { "dest": "JFK", "hours": 5.5, "dist": 4162, "orig": "SFO" }, { "dest": "ZRH", "hours": 10.916666666666666, "dist": 7993, "orig": "PEK" }, { "dest": "YOW", "hours": 10.133333333333333, "dist": 7758, "orig": "HNL" }, { "dest": "BER", "hours": 1.15, "dist": 676, "orig": "VIE" }, { "dest": "TIP", "hours": 3.0166666666666666, "dist": 2019, "orig": "CDG" }, { "dest": "ATZ", "hours": 4.783333333333333, "dist": 3453, "orig": "CDG" }, { "dest": "FCO", "hours": 1.8666666666666667, "dist": 1102, "orig": "CDG" }, { "dest": "FCO", "hours": 1.4666666666666668, "dist": 780, "orig": "VIE" }, { "dest": "AMM", "hours": 5.65, "dist": 4138, "orig": "LIS" }, { "dest": "BER", "hours": 3.3666666666666667, "dist": 2307, "orig": "LIS" }, { "dest": "WAW", "hours": 3.9166666666666665, "dist": 2754, "orig": "LIS" }, { "dest": "SVO", "hours": 7.716666666666667, "dist": 5811, "orig": "PEK" }, { "dest": "HUU", "hours": 13.333333333333334, "dist": 10331, "orig": "BRN" } ]
loads
läd diese Datenstruktur aus der Zeichenkette:
flightimes_py2 = json.loads(flighttimes_json)
print(flightimes_py2[1])
{u'dest': u'JFK', u'hours': 8.983333333333333, u'dist': 6823, u'orig': u'VIE'}
YAML ist ähnlich wie JSON ein textbasiertes, programmiersprachenunabhängiges Format zur strukturierten Speicherung von Daten. Im Vergleich zu JSON hat es einige zusätzliche Funktionen und ist für den Menschen besser lesbar.
Im folgenden wird die externe Bibliothek pyyaml verwendet, um ganz analog zu JSON die Daten zuerst als String zu kodieren und dann wieder zurück zu lesen.
import yaml
flightimes_yaml = yaml.dump(flighttimes_py, default_flow_style=False, indent=2)
print(flightimes_yaml)
- dest: LHR dist: 1100 hours: 2.5 orig: VIE - dest: JFK dist: 6823 hours: 8.983333333333333 orig: VIE - dest: ZCL dist: 3346 hours: 4.65 orig: JFK - dest: JFK dist: 4162 hours: 5.5 orig: SFO - dest: ZRH dist: 7993 hours: 10.916666666666666 orig: PEK - dest: YOW dist: 7758 hours: 10.133333333333333 orig: HNL - dest: BER dist: 676 hours: 1.15 orig: VIE - dest: TIP dist: 2019 hours: 3.0166666666666666 orig: CDG - dest: ATZ dist: 3453 hours: 4.783333333333333 orig: CDG - dest: FCO dist: 1102 hours: 1.8666666666666667 orig: CDG - dest: FCO dist: 780 hours: 1.4666666666666668 orig: VIE - dest: AMM dist: 4138 hours: 5.65 orig: LIS - dest: BER dist: 2307 hours: 3.3666666666666667 orig: LIS - dest: WAW dist: 2754 hours: 3.9166666666666665 orig: LIS - dest: SVO dist: 5811 hours: 7.716666666666667 orig: PEK - dest: HUU dist: 10331 hours: 13.333333333333334 orig: BRN
Im Gegensatz zu JSON, gibt es keine geschwungenen Klammern und sonstige besondere Auszeichnungen. Der Bindestrich signalisiert einen neuen Eintrag und die mit Doppelpunkt getrennte Assoziation ist eine kompaktere Darstellung.
Mit wenigen Parameteränderungen gibt es aber auch ausgaben, die bis auf kleine Zeichenkodierungsunterschiede wie JSON sind. Daher ist YAML eine Übermenge von JSON.
flightimes_yaml2 = yaml.dump(flighttimes_py, default_flow_style=True, indent=0)
print(flightimes_yaml2)
[{dest: LHR, dist: 1100, hours: 2.5, orig: VIE}, {dest: JFK, dist: 6823, hours: 8.983333333333333, orig: VIE}, {dest: ZCL, dist: 3346, hours: 4.65, orig: JFK}, {dest: JFK, dist: 4162, hours: 5.5, orig: SFO}, {dest: ZRH, dist: 7993, hours: 10.916666666666666, orig: PEK}, {dest: YOW, dist: 7758, hours: 10.133333333333333, orig: HNL}, {dest: BER, dist: 676, hours: 1.15, orig: VIE}, {dest: TIP, dist: 2019, hours: 3.0166666666666666, orig: CDG}, {dest: ATZ, dist: 3453, hours: 4.783333333333333, orig: CDG}, {dest: FCO, dist: 1102, hours: 1.8666666666666667, orig: CDG}, {dest: FCO, dist: 780, hours: 1.4666666666666668, orig: VIE}, {dest: AMM, dist: 4138, hours: 5.65, orig: LIS}, {dest: BER, dist: 2307, hours: 3.3666666666666667, orig: LIS}, {dest: WAW, dist: 2754, hours: 3.9166666666666665, orig: LIS}, {dest: SVO, dist: 5811, hours: 7.716666666666667, orig: PEK}, {dest: HUU, dist: 10331, hours: 13.333333333333334, orig: BRN}]
flightimes_yaml3 = yaml.dump(flighttimes_py, default_flow_style=None, indent=0)
print(flightimes_yaml3)
- {dest: LHR, dist: 1100, hours: 2.5, orig: VIE} - {dest: JFK, dist: 6823, hours: 8.983333333333333, orig: VIE} - {dest: ZCL, dist: 3346, hours: 4.65, orig: JFK} - {dest: JFK, dist: 4162, hours: 5.5, orig: SFO} - {dest: ZRH, dist: 7993, hours: 10.916666666666666, orig: PEK} - {dest: YOW, dist: 7758, hours: 10.133333333333333, orig: HNL} - {dest: BER, dist: 676, hours: 1.15, orig: VIE} - {dest: TIP, dist: 2019, hours: 3.0166666666666666, orig: CDG} - {dest: ATZ, dist: 3453, hours: 4.783333333333333, orig: CDG} - {dest: FCO, dist: 1102, hours: 1.8666666666666667, orig: CDG} - {dest: FCO, dist: 780, hours: 1.4666666666666668, orig: VIE} - {dest: AMM, dist: 4138, hours: 5.65, orig: LIS} - {dest: BER, dist: 2307, hours: 3.3666666666666667, orig: LIS} - {dest: WAW, dist: 2754, hours: 3.9166666666666665, orig: LIS} - {dest: SVO, dist: 5811, hours: 7.716666666666667, orig: PEK} - {dest: HUU, dist: 10331, hours: 13.333333333333334, orig: BRN}
Zurücklesen des YAML Datensatzes in ein Python Objekt:
flightimes_py3 = yaml.load(flightimes_yaml)
print(flightimes_py3[1])
{'dest': 'JFK', 'hours': 8.983333333333333, 'dist': 6823, 'orig': 'VIE'}
Ein sehr altes, ebenfalls programmiersprachenunabhängiges und textbasiertes, Serialisierungsformat ist XML. Das dahinterstehende Konzept ist ein Baum, dessen Wurzelknoten das gesamte Dokument umfasst. Jeder Knoten kann Attribute und Kinderknoten haben. Zwischen den Kinderknoten können auch Textknoten stehen.
Man trifft es nur noch selten an und wird am ehesten noch im Geschäftsumfeld verwendet.
Das in Python eingebaute xml
(xml
in python 3) modul stellt beispielsweise über das Submodul minidom
und etree
einfache Schnittstelle zum Verarbeiten von XML bereit.
HTML ist ähnlich zu XML, und daher sind einige Bibliotheken zum automatisierten Verarbeiten von HTML auf basis von XML konstruiert.
import xml.etree.ElementTree as ET
# wurzelknoten
flighttimes_xml = ET.Element("flighttimes")
for _, data in flighttimes.iterrows():
ft_entry = ET.SubElement(flighttimes_xml, "flighttime")
ft_entry.set("orig", data.origin)
ft_entry.set("dest", data.destination)
ft_distance = ET.SubElement(ft_entry, "distance")
ft_distance.set("unit", "km")
ft_distance.text = str(data.distance)
ft_hours = ET.SubElement(ft_entry, "hours")
ft_hours.set("unit", "hour")
ft_hours.text = str(data.time2)
Zur schöneren Formatierung, wird das Ergebnis von ET.tostring
noch durch minidom
's toprettyxml
geschickt.
from xml.dom import minidom
raw_xml = ET.tostring(flighttimes_xml, "UTF-8")
flighttimes_xml_ser = minidom.parseString(raw_xml).toprettyxml(indent=" ")
print(flighttimes_xml_ser)
<?xml version="1.0" ?> <flighttimes> <flighttime dest="LHR" orig="VIE"> <distance unit="km">1100</distance> <hours unit="hour">2.5</hours> </flighttime> <flighttime dest="JFK" orig="VIE"> <distance unit="km">6823</distance> <hours unit="hour">8.98333333333</hours> </flighttime> <flighttime dest="ZCL" orig="JFK"> <distance unit="km">3346</distance> <hours unit="hour">4.65</hours> </flighttime> <flighttime dest="JFK" orig="SFO"> <distance unit="km">4162</distance> <hours unit="hour">5.5</hours> </flighttime> <flighttime dest="ZRH" orig="PEK"> <distance unit="km">7993</distance> <hours unit="hour">10.9166666667</hours> </flighttime> <flighttime dest="YOW" orig="HNL"> <distance unit="km">7758</distance> <hours unit="hour">10.1333333333</hours> </flighttime> <flighttime dest="BER" orig="VIE"> <distance unit="km">676</distance> <hours unit="hour">1.15</hours> </flighttime> <flighttime dest="TIP" orig="CDG"> <distance unit="km">2019</distance> <hours unit="hour">3.01666666667</hours> </flighttime> <flighttime dest="ATZ" orig="CDG"> <distance unit="km">3453</distance> <hours unit="hour">4.78333333333</hours> </flighttime> <flighttime dest="FCO" orig="CDG"> <distance unit="km">1102</distance> <hours unit="hour">1.86666666667</hours> </flighttime> <flighttime dest="FCO" orig="VIE"> <distance unit="km">780</distance> <hours unit="hour">1.46666666667</hours> </flighttime> <flighttime dest="AMM" orig="LIS"> <distance unit="km">4138</distance> <hours unit="hour">5.65</hours> </flighttime> <flighttime dest="BER" orig="LIS"> <distance unit="km">2307</distance> <hours unit="hour">3.36666666667</hours> </flighttime> <flighttime dest="WAW" orig="LIS"> <distance unit="km">2754</distance> <hours unit="hour">3.91666666667</hours> </flighttime> <flighttime dest="SVO" orig="PEK"> <distance unit="km">5811</distance> <hours unit="hour">7.71666666667</hours> </flighttime> <flighttime dest="HUU" orig="BRN"> <distance unit="km">10331</distance> <hours unit="hour">13.3333333333</hours> </flighttime> </flighttimes>
Zurücklesen, diesmal über minidom
:
flighttimes_dom = minidom.parseString(flighttimes_xml_ser)
ft_dom_root = flighttimes_dom.firstChild
ft_dom_node1 = ft_dom_root.childNodes[1]
print(ft_dom_node1.toxml())
<flighttime dest="LHR" orig="VIE"> <distance unit="km">1100</distance> <hours unit="hour">2.5</hours> </flighttime>
ft_dom_node1.getAttribute("orig")
u'VIE'
ft_dom_node1.getAttribute("dest")
u'LHR'
Man beachte, dass hier weit mehr Aufwand getätigt werden muss und es auch keinerlei Unterstützung für Datentypen gibt.
.getElementsByTagName
sucht anch allen Kindknoten mit dem angegebenen Namen -- es wird mittels [0]
das aller erste genommen..childNodes[0]
weiter den Baum hinab, um in dieser TextNode
dann über das .data
Attribut endlich zu dem eigentlichen Wert zu gelangen.distance_node = ft_dom_node1.getElementsByTagName("distance")[0]
unit = distance_node.getAttribute("unit")
value = int(distance_node.childNodes[0].data)
print("%d [%s]" % (value, unit))
1100 [km]
hours_node = ft_dom_node1.getElementsByTagName("hours")[0]
unit = hours_node.getAttribute("unit")
value = float(hours_node.childNodes[0].data)
print("%f [%s]" % (value, unit))
2.500000 [hour]