Pythonmania

Script Different!

Suchen in:
Suche:
Startseite | Schockwellenreiter | Impressum
Navigation
Artikel zu Python
Warum Python?
Hallo Welt
Wie alt ist der Kapitän?
Schmetterlingskurve
Apfelmännchen
Dancing Python
User-Agenten
fakeMail()
Template Engine
Python & XML (1)
wxPython (1)
wxPython (2)
wxPython (3)

How To's
ftp mit Python
Filedialog
Piddle und Mac OS X
XML-RPC
Blogger API

Zope und Python
ZWiki und Plone
Navigation und DTML
»Last Update«

Book Reviews
Python und Tkinter
Python Cookbook

Alte Artikel
O'Reilly
MacPython & Tkinter (d)
MacPython & Tkinter (e)
Modul W
Easy Dialogs
File Dialogs

Archiv
Oktober 2009
Juni 2009
Mai 2009
April 2009
März 2009
Februar 2009
Januar 2009
Dezember 2008
November 2008
Oktober 2008
September 2008
August 2008
Juli 2008
Juni 2008
Mai 2008
April 2008
März 2008
Februar 2008
Januar 2008
Dezember 2007
November 2007
Oktober 2007
September 2007
August 2007
Juli 2007
Juni 2007
Mai 2007
April 2007
März 2007
Februar 2007
Januar 2007
Dezember 2006
November 2006
Oktober 2006
September 2006
August 2006
Juli 2006
Juni 2006
Mai 2006
April 2006
März 2006
Februar 2006
Januar 2006
Dezember 2005
November 2005
Oktober 2005
September 2005
August 2005
Juli 2005
Juni 2005
Mai 2005
April 2005
März 2005
Februar 2005

RSS Icon
[フレーム]
Anzeigen
[フレーム]

Notebook

Python und XML - Teil 1

Ein Mini-Weblog-Tool mit Python und XML

Python & XML Book Cover [Python & XML] (statt einer Besprechung): Das Buch Python & XML von Christopher A. Jones und Fred L. Drake, Jr. ist wunderbar. Doch statt einer ultimativen Lobhudelei möchte ich zwei Scripte veröffentlichen, die ich -- inspiriert durch die Beispiele in Kapitel 4 des Buches -- geschrieben habe. Sie folgen in weiten Teilen dem Buch, sind aber so abgewandelt, daß sie als Grundlage für ein Mini-Weblog-Tool auf XML-Basis benutzt werden können.

[Die Klasse Artikel]: Die Klasse Artikel ist ein kleine Klasse. Sie exportiert nur zwei Methoden, eine Methode, die aus einem Artikel eine XML-Representation erstellt, und eine Methode, die umgekehrt aus einer XML-Representation wieder einen String generiert. Diese Methode arbeitet mit minidom. Die DOM-Implementierung ist Teil der Python-Standard-Distribution.

import xml.dom.minidom
from xml.sax.saxutils import escape

class Article:
""" Ein Artikel und seine Metadaten. """

def __init__(self):
""" Alles zurücksetzen. """
self.reset()

def reset(self):
self.title = ""
self.source = ""
self.size = 0
self.when = ""
self.description = ""
# self.categories = ""
def getXML(self):
""" Generiert das XML für den Artikel. """

attr = ''
if self.title:
attr = ' title="%s"' % escape(self.title)
s = '<?xml version="1.0"?>\n<item%s>\n' % attr
if self.source:
s = '%s\t<source url="%s" />\n' % (s, escape(self.source))
if self.description:
s = '%s\t<description>\n%s\n\t</description>\n' % (s, escape(self.description))
return s + '</item>\n'

def fromXML(self, data):
""" data ist ein XML-Dokument, das als String übergeben wird. """
self.reset()
dom = xml.dom.minidom.parseString(data)
self.title = get_attribute(dom, "item", "title")
self.source = get_attribute(dom, "source", "url")
self.size = int(get_attribute(dom, "size", "bytes") or 0)
self.when = get_attribute(dom, "when", "stime")
nodelist = dom.getElementsByTagName("description")
if nodelist:
assert len(nodelist) == 1
description = nodelist[0]
description.normalize()
if description.childNodes:
self.description = description.firstChild.data.strip()

# Hilfsfunktionen:

def get_attribute(dom, tagname, attrname):
""" Gibt den Wert eines Attributs zurück, falls vorhanden. """
nodelist = dom.getElementsByTagName(tagname)
if nodelist:
assert len(nodelist) == 1
node = nodelist[0]
return node.getAttribute(attrname).strip()
else:
return ""

Wir machen hier massiv Gebrauch von Pythons string formatting expressions, die ähnlich funktionieren, wie das von C bekannte sprintf. Dabei werden links vom % stehende %s durch die rechts vom % stehende Strings ersetzt.

Beachtet außerdem die escape-Funktion (aus xml.sax.saxutils), die dafür sorgt, daß eventuelle Zeichen, die in XML maskiert werden müssen, auch maskiert werden.

Die fromXML-Methode benutzt das DOM um die benötigten Informationen aus dem XML herauszuklauben.

Jetzt kann man schon einmal testweise im Interpreter eingeben:

>>> from article import Article
>>> art = Article()
>>> art.title = "Erstes Posting"
>>> art.description = "Dies ist mein erstes Posting."
>>> print art.getXML()
<?xml version="1.0"?>
<item title="Erstes Posting">
<description>
Dies ist mein erstes Posting.
</description>
</item>

[Die Klasse Storage]: Jetzt benötigen wir als nächstes eine Klasse, die die generierten XML-Strings als Datei ins Filesystem schreibt und die XML-Dateien lesen und für die weitere Bearbeitung aufbereiten kann. Auch diese Klasse ist wieder sehr klein.

from article import Article
import string, os

class Storage:
""" Speichert und lädt Artikel-Objekte als XML-Files.
-- sollte einfach für eine Datenbank zu adaptieren sein. """

def save(self, article):
""" Speichert als <article.title>.xml. Entfernt vorher alle
Leerzeichen aus dem Titel. """

# Einen einigermaßen sicheren Dateinamen aus dem Titel konstruieren:
sf = string.replace(article.title, " ", "")
sf = string.replace(sf, os.sep, "")
sf = string.replace(sf, ".", "")
sf = sf[:25]
sf += ".xml"
fd = open(sf, "w")

# Schreibt die Daten via getXML() auf die Platte:
fd.write(article.getXML())
fd.close()

def load(self, sName):
""" sName in der Form *.xml. Gibt ein
Article Object zurück. """
fd = open(sName, "r")
sxml = fd.read()

# Erzeuge eine Article Instance:
art = Article()

# Erzeuge ein Article Object via fromXML():
art.fromXML(sxml)
fd.close()

return art

Beide Methoden sind eigentlich trivial und tun exakt das, was ihr Name sagt: load lädt eine XML-Datei und generiert eine Instanz der Klasse Article und save schreibt eine Instanz der Klasse Article als XML-Datei auf die Festplatte.

Die umständliche Generierung eines Dateinamens aus dem Titel ist aus zweierlei Hinsicht eigentlich unnötig. Einmal wird man bei einer ernsthaften Anwendung sicher nicht einen Dateinamen aus dem Titel generieren, sondern sich irgendetwas anderes -- z.B. eine fortlaufende Numerierung -- überlegen und zweitens erinnere ich mich, irgendwo in der Dokumentation einmal eine Methode in irgendeinem Modul gefunden zu haben, die einen sicheren Dateinamen konstruiert. Nur -- ich konnte diese Methode nicht wiederfinden...

Diese beiden Klassen können auch ohne CGI-Modul lokal auf dem Rechner getestet werden. Sie sind völlig unabhängig von der geplanten Anwendung und daher vielleicht auch anderswo nützlich. Dies ist einer der Vorteile der Objektorientierung, wie Python sie bietet.

In der Fortsetzung dieser kleinen Artikelreihe werden wir ein CGI-Skript entwickeln, das diese beiden Methoden benutzt und mit Hilfe meiner kleinen Template-Engine ein Mini-Weblog-Tool daraus basteln.

Zum Schluß möchte ich noch einmal auf Python & XML hinweisen, das mich zu diesem Artikelchen inspiriert hat und woraus ich auch sehr viel Code geborgt habe. Es ist absolut lesenswert und ein must have für jeden, der sich mit Python und XML beschäftigt oder beschäftigen will.

Wie immer gibt es bei O'Reilly ein Probekapitel online. Diesmal das erste Kapitel Python and XML, das eine kleine Übersicht über XML, SAX, DOM und die Tools, die in Python für die Bearbeitung von XML zur Verfügung stehen, gibt.






Werbung:

Letzte Änderung: 16.08.2010; 16:09:20 Uhr | © Copyright: 2000 - 2010 by Kantel-Chaos-Team | Kontakt: der@schockwellenreiter.de

frontierLogo picture Made with a Mac Weblog Commenting and Trackback by HaloScan.com CC-Logo Site Meter

AltStyle によって変換されたページ (->オリジナル) /