Archive for Juni, 2007

XML mit Python: lxml

Mittwoch, Juni 13th, 2007

Unter den XML Bibliotheken für die Programmiersprache Python ist lxml.etree ein wahres Goldstück. Es schafft den schwierigen Spagat, die extrem schnellen XML-Bibliotheken libxml2 und libxslt hinter einer pythonesquen und spielend leicht zu verwendenden Schnittstelle zu verstecken: der ElementTree API, die es um so praktische und effiziente XML-Werkzeuge wie XPath oder XSLT erweitert. lxml ist leicht in Python zu erweitern und sogar so flexibel, dass es die Implementierung beliebiger XML-Schnittstellen erlaubt.

Das lxml Projekt bemüht sich, eine portable Python-Erweiterung anzubieten, die einfach mit easy-install zu installieren ist. Unter den meisten Betriebsystemen funktioniert das problemlos mit einem

    easy_install lxml

Da eine Installation von Hand unter Windows wie üblich etwas komplizierter ist, stehen dafür fertig kompilierte Binaries zur Verfügung. Auf anderen Plattformen kümmert sich EasyInstall automatisch um das Kompilieren und Installieren. Danach reicht ein Import und lxml.etree steht zur Verfügung:

    >>> from lxml import etree

Die wichtigste API Klasse heißt einfach Element. Es ist eine Container-Klasse, die sich wie verschiedene aus Python bekannte Standardklassen verhält. Um ein Element anzulegen, reicht ein Aufruf der entsprechenden Factory-Funktion:

    >>> wurzel = etree.Element("wurzel")

Dadurch wird ein XML Element mit dem Tag-Namen “wurzel” erzeugt. Um den Tag-Namen abzufragen gibt es das Attribut tag:

    >>> print wurzel.tag
    wurzel

XML ist eine Baumstruktur, und so sind auch Elemente in Bäumen organisiert. Um dem Wurzelelement ein Kindelement hinzuzufügen, kann die append() Methode verwendet werden:

    >>> wurzel.append( etree.Element("kind1") )

Da diese Operation extrem häufig verwendet wird, gibt es eine weitere Factory-Funktion SubElement(), die dies einfach und effizient erledigt. Sie wird genauso verwendet wie die Element() Factory, erhält jedoch zusätzlich ein Elternelement als ersten Parameter:

    >>> kind2 = etree.SubElement(wurzel, "kind2")
    >>> kind3 = etree.SubElement(wurzel, "kind3")

Um dann schließlich noch sehen zu können, dass das Ganze auch wirklich XML ist, lässt es sich über die tostring() Funktion serialisieren:

    >>> print etree.tostring(wurzel, pretty_print=True)
    <wurzel>
      <kind1/>
      <kind2/>
      <kind3/>
    </wurzel>

Schon diese kleinen Beispiele zeigen, wie einfach die Erstellung von XML Dokumenten mit lxml.etree ist. Weiter Beispiele finden sich im (englischsprachigen) lxml.etree Tutorial, von dem ich hier von Zeit zu Zeit ein wenig wiedergeben werde.