lxml FAQ - Frequently Asked Questions

Frequently asked questions on lxml. See also the notes on compatibility to ElementTree.

Contents

The code examples below use the lxml.etree module:

>>> from lxml import etree

General Questions

Is there a tutorial?

Read the lxml.etree Tutorial. While this is still work in progress (just as any good documentation), it provides an overview of the most important concepts in lxml.etree. If you want to help out, improving the tutorial is a very good place to start.

There is also a tutorial for ElementTree which works for lxml.etree. The documentation of the extended etree API also contains many examples for lxml.etree. Fredrik Lundh's element library contains a lot of nice recipes that show how to solve common tasks in ElementTree and lxml.etree. To learn using lxml.objectify, read the objectify documentation.

John Shipman has written another tutorial called Python XML processing with lxml that contains lots of examples. Liza Daly wrote a nice article about high-performance aspects when parsing large files with lxml.

Where can I find more documentation about lxml?

There is a lot of documentation on the web and also in the Python standard library documentation, as lxml implements the well-known ElementTree API and tries to follow its documentation as closely as possible. The recipes in Fredrik Lundh's element library are generally worth taking a look at. There are a couple of issues where lxml cannot keep up compatibility. They are described in the compatibility documentation.

The lxml specific extensions to the API are described by individual files in the doc directory of the source distribution and on the web page.

The generated API documentation is a comprehensive API reference for the lxml package.

What standards does lxml implement?

The compliance to XML Standards depends on the support in libxml2 and libxslt. Here is a quote from http://xmlsoft.org/:

In most cases libxml2 tries to implement the specifications in a relatively strictly compliant way. As of release 2.4.16, libxml2 passed all 1800+ tests from the OASIS XML Tests Suite.

lxml currently supports libxml2 2.6.20 or later, which has even better support for various XML standards. The important ones are:

  • XML 1.0
  • HTML 4 (recent libxml2 versions implement parts of HTML 5)
  • XML namespaces
  • XML Schema 1.0
  • XPath 1.0
  • XInclude 1.0
  • XSLT 1.0
  • EXSLT
  • XML catalogs
  • canonical XML
  • RelaxNG
  • xml:id
  • xml:base

Support for XML Schema is currently not 100% complete in libxml2, but is definitely very close to compliance. Schematron is supported in two ways, the best being the original ISO Schematron reference implementation via XSLT. libxml2 also supports loading documents through HTTP and FTP.

For RelaxNG Compact Syntax support, there is a tool called rnc2rng, written by David Mertz, which you might be able to use from Python. Failing that, trang is the 'official' command line tool (written in Java) to do the conversion.

Who uses lxml?

As an XML library, lxml is often used under the hood of in-house server applications, such as web servers or applications that facilitate some kind of content management. Many people who deploy Zope, Plone or Django use it together with lxml in the background, without speaking publicly about it. Therefore, it is hard to get an idea of who uses it, and the following list of 'users and projects we know of' is very far from a complete list of lxml's users.

Also note that the compatibility to the ElementTree library does not require projects to set a hard dependency on lxml - as long as they do not take advantage of lxml's enhanced feature set.

  • cssutils, a CSS parser and toolkit, can be used with lxml.cssselect
  • Deliverance, a content theming tool
  • Enfold Proxy 4, a web server accelerator with on-the-fly XSLT processing
  • Inteproxy, a secure HTTP proxy
  • lwebstring, an XML template engine
  • openpyxl, a library to read/write MS Excel 2007 files
  • OpenXMLlib, a library for handling OpenXML document meta data
  • PsychoPy, psychology software in Python
  • Pycoon, a WSGI web development framework based on XML pipelines
  • pycsw, an OGC CSW server implementation written in Python
  • PyQuery, a query framework for XML/HTML, similar to jQuery for JavaScript
  • python-docx, a package for handling Microsoft's Word OpenXML format
  • Rambler, news aggregator on Runet
  • rdfadict, an RDFa parser with a simple dictionary-like interface.
  • xupdate-processor, an XUpdate implementation for lxml.etree
  • Diazo, an XSLT-under-the-hood web site theming engine

Zope3 and some of its extensions have good support for lxml:

  • gocept.lxml, Zope3 interface bindings for lxml
  • z3c.rml, an implementation of ReportLab's RML format
  • zif.sedna, an XQuery based interface to the Sedna OpenSource XML database

And don't miss the quotes by our generally happy users, and other sites that link to lxml. As Liza Daly puts it: "Many software products come with the pick-two caveat, meaning that you must choose only two: speed, flexibility, or readability. When used carefully, lxml can provide all three."

What is the difference between lxml.etree and lxml.objectify?

The two modules provide different ways of handling XML. However, objectify builds on top of lxml.etree and therefore inherits most of its capabilities and a large portion of its API.

  • lxml.etree is a generic API for XML and HTML handling. It aims for ElementTree compatibility and supports the entire XML infoset. It is well suited for both mixed content and data centric XML. Its generality makes it the best choice for most applications.

  • lxml.objectify is a specialized API for XML data handling in a Python object syntax. It provides a very natural way to deal with data fields stored in a structurally well defined XML format. Data is automatically converted to Python data types and can be manipulated with normal Python operators. Look at the examples in the objectify documentation to see what it feels like to use it.

    Objectify is not well suited for mixed contents or HTML documents. As it is built on top of lxml.etree, however, it inherits the normal support for XPath, XSLT or validation.

How can I make my application run faster?

lxml.etree is a very fast library for processing XML. There are, however, a few caveats involved in the mapping of the powerful libxml2 library to the simple and convenient ElementTree API. Not all operations are as fast as the simplicity of the API might suggest, while some use cases can heavily benefit from finding the right way of doing them. The benchmark page has a comparison to other ElementTree implementations and a number of tips for performance tweaking. As with any Python application, the rule of thumb is: the more of your processing runs in C, the faster your application gets. See also the section on threading.

What about that trailing text on serialised Elements?

The ElementTree tree model defines an Element as a container with a tag name, contained text, child Elements and a tail text. This means that whenever you serialise an Element, you will get all parts of that Element:

>>> root = etree.XML("<root><tag>text<child/></tag>tail</root>")
>>> print(etree.tostring(root[0]))
<tag>text<child/></tag>tail

Here is an example that shows why not serialising the tail would be even more surprising from an object point of view:

>>>