The XSLT C library for GNOME

libxslt

Libxslt is the XSLT C library developed for the GNOME project. XSLT itself is a an XML language to define transformation for XML. Libxslt is based on libxml2 the XML C library developed for the GNOME project. It also implements most of the EXSLT set of processor-portable extensions functions and some of Saxon's evaluate and expressions extensions.

People can either embed the library in their application or use xsltproc the command line processing tool. This library is free software and can be reused in commercial applications (see the intro)

External documents:

Logo designed by Marc Liyanage.

Introduction

This document describes libxslt, the XSLT C library developed for the GNOME project.

Here are some key points about libxslt:

Documentation

There are some on-line resources about using libxslt:

  1. Check the API documentation automatically extracted from code comments (using the program apibuild.py, developed for libxml, together with the xsl script 'newapi.xsl' and the libxslt xsltproc program).
  2. Look at the mailing-list archive.
  3. Of course since libxslt is based on libxml, it's a good idea to at least read libxml description

Reporting bugs and getting help

If you need help with the XSLT language itself, here are a number of useful resources:

Well, bugs or missing features are always possible, and I will make a point of fixing them in a timely fashion. The best way to report a bug is to use the GNOME bug tracking database (make sure to use the "libxslt" module name). Before filing a bug, check the list of existing libxslt bugs to make sure it hasn't already been filed. I look at reports there regularly and it's good to have a reminder when a bug is still open. Be sure to specify that the bug is for the package libxslt.

For small problems you can try to get help on IRC, the #xml channel on irc.gnome.org (port 6667) usually have a few person subscribed which may help (but there is no guarantee and if a real issue is raised it should go on the mailing-list for archival).

There is also a mailing-list xslt@gnome.org for libxslt, with an on-line archive. To subscribe to this list, please visit the associated Web page and follow the instructions.

Alternatively, you can just send the bug to the xslt@gnome.org list, if it's really libxslt related I will approve it.. Please do not send me mail directly especially for portability problem, it makes things really harder to track and in some cases I'm not the best person to answer a given question, ask the list instead. Do not send code, I won't debug it (but patches are really appreciated!).

Please note that with the current amount of virus and SPAM, sending mail to the list without being subscribed won't work. There is *far too many bounces* (in the order of a thousand a day !) I cannot approve them manually anymore. If your mail to the list bounced waiting for administrator approval, it is LOST ! Repost it and fix the problem triggering the error. Also please note that emails with a legal warning asking to not copy or redistribute freely the information they contain are NOT acceptable for the mailing-list, such mail will as much as possible be discarded automatically, and are less likely to be answered if they made it to the list, DO NOT post to the list from an email address where such legal requirements are automatically added, get private paying support if you can't share information.

Check the following too before posting:

Then send the bug with associated information to reproduce it to the xslt@gnome.org list; if it's really libxslt related I will approve it. Please do not send mail to me directly, it makes things really hard to track and in some cases I am not the best person to answer a given question, ask on the list.

To be really clear about support:

Of course, bugs reports with a suggested patch for fixing them will probably be processed faster.

If you're looking for help, a quick look at the list archive may actually provide the answer, I usually send source samples when answering libxslt usage questions. The auto-generated documentation is not as polished as I would like (I need to learn more about Docbook), but it's a good starting point.

How to help

You can help the project in various ways, the best thing to do first is to subscribe to the mailing-list as explained before, check the archives and the GNOME bug database::

  1. provide patches when you find problems
  2. provide the diffs when you port libxslt to a new platform. They may not be integrated in all cases but help pinpointing portability problems and
  3. provide documentation fixes (either as patches to the code comments or as HTML diffs).
  4. provide new documentations pieces (translations, examples, etc ...)
  5. Check the TODO file and try to close one of the items
  6. take one of the points raised in the archive or the bug database and provide a fix. Get in touch with me before to avoid synchronization problems and check that the suggested fix will fit in nicely :-)

Downloads

The latest versions of libxslt can be found on the xmlsoft.org server and on mirrors (France) or on the GNOME FTP server as a source archive, Antonin Sprinzl also provides a mirror in Austria. (NOTE that you need the libxml2, libxml2-devel, libxslt and libxslt-devel packages installed to compile applications using libxslt.) Igor Zlatkovic is now the maintainer of the Windows port, he provides binaries. CSW provides Solaris binaries, and Steve Ball provides Mac Os X binaries.

Contribs:

I do accept external contributions, especially if compiling on another platform, get in touch with me to upload the package. I will keep them in the contrib directory

Libxslt is also available from SVN:

FAQ

  1. Troubles compiling or linking programs using libxslt

    Usually the problem comes from the fact that the compiler doesn't get the right compilation or linking flags. There is a small shell script xslt-config which is installed as part of libxslt usual install process which provides those flags. Use

    xslt-config --cflags

    to get the compilation flags and

    xslt-config --libs

    to get the linker flags. Usually this is done directly from the Makefile as:

    CFLAGS=`xslt-config --cflags`

    LIBS=`xslt-config --libs`

    Note also that if you use the EXSLT extensions from the program then you should prepend -lexslt to the LIBS options

  2. passing parameters on the xsltproc command line doesn't work

    xsltproc --param test alpha foo.xsl foo.xml

    the param does not get passed and ends up as ""

    In a nutshell do a double escaping at the shell prompt:

    xsltproc --param test "'alpha'" foo.xsl foo.xml

    i.e. the string value is surrounded by " and ' then terminated by ' and ". Libxslt interpret the parameter values as XPath expressions, so the string ->alpha<- is intepreted as the node set matching this string. You really want ->'alpha'<- to be passed to the processor. And to allow this you need to escape the quotes at the shell level using ->"'alpha'"<- .

    or use

    xsltproc --stringparam test alpha foo.xsl foo.xml

  3. Is there C++ bindings ?

    Yes for example xmlwrapp , see the related pages about bindings

News

The change log describes the recents commits to the SVN code base.

Those are the public releases made:

1.1.26: Sep 24 2009

1.1.25: Sep 17 2009

1.1.24: May 13 2008

1.1.23: Apr 8 2008

1.1.22: Aug 23 2007

1.1.21: Jun 12 2007

1.1.20: Jan 17 2007

1.1.19: Nov 29 2006

1.1.18: Oct 26 2006

1.1.17: Jun 6 2006

1.1.16: May 01 2006

1.1.15: Sep 04 2005

1.1.14: Apr 02 2005

1.1.13: Mar 13 2005

1.1.12: Oct 29 2004

1.1.11: Sep 29 2004

1.1.10: Aug 31 2004

1.1.9: Aug 22 2004

1.1.8: July 5 2004

1.1.7: May 17 2004

1.1.6: Apr 18 2004

1.1.5: Mar 23 2004

1.1.4: Feb 23 2004

1.1.3: Feb 16 2004

1.1.2: Dec 24 2003

1.1.1: Dec 10 2003

1.1.0: Nov 4 2003

1.0.33: Sep 12 2003

This is a bugfix only release

1.0.32: Aug 9 2003

1.0.31: Jul 6 2003

1.0.30: May 4 2003

1.0.29: Apr 1 2003

1.0.28: Mar 24 2003

1.0.27: Feb 24 2003

1.0.26: Feb 10 2003

1.0.25: Feb 5 2003

1.0.24: Jan 14 2003

1.0.23: Nov 17 2002

1.0.22: Oct 18 2002

1.0.21: Sep 26 2002

1.0.20: Aug 23 2002

1.0.19: July 6 2002

1.0.18: May 27 2002

1.0.17: April 29 2002

1.0.16: April 15 2002

1.0.15: Mar 25 2002

1.0.14: Mar 18 2002

1.0.13: Mar 8 2002

1.0.12: Feb 11 2002

1.0.11: Feb 8 2002

1.0.10: Jan 14 2002

1.0.9: Dec 7 2001

1.0.8: Nov 26 2001

1.0.7: Nov 10 2001

1.0.6: Oct 30 2001

1.0.5: Oct 10 2001

1.0.4: Sep 12 2001

1.0.3: Aug 23 2001

1.0.2: Aug 15 2001

1.0.1: July 24 2001

1.0.0: July 10 2001

0.14.0: July 5 2001

0.13.0: June 26 2001

0.12.0: June 18 2001

0.11.0: June 1 2001

Mostly a bug fix release.

0.10.0: May 19 2001

0.9.0: May 3 2001

0.8.0: Apr 22 2001

0.7.0: Apr 10 2001

0.6.0: Mar 22 2001

0.5.0: Mar 10 2001

0.4.0: Mar 1 2001

0.3.0: Feb 24 2001

0.2.0: Feb 15 2001

0.1.0: Feb 8 2001

0.0.1: Jan 25 2001

The xsltproc tool

This program is the simplest way to use libxslt: from the command line. It is also used for doing the regression tests of the library.

It takes as first argument the path or URL to an XSLT stylesheet, the next arguments are filenames or URIs of the inputs to be processed. The output of the processing is redirected on the standard output. There is actually a few more options available:

orchis:~ -> xsltproc
Usage: xsltproc [options] stylesheet file [file ...]
   Options:
      --version or -V: show the version of libxml and libxslt used
      --verbose or -v: show logs of what's happening
      --output file or -o file: save to a given file
      --timing: display the time used
      --repeat: run the transformation 20 times
      --debug: dump the tree of the result instead
      --novalid: skip the Dtd loading phase
      --noout: do not dump the result
      --maxdepth val : increase the maximum depth
      --html: the input document is(are) an HTML file(s)
      --docbook: the input document is SGML docbook
      --param name value : pass a (parameter,value) pair
      --nonet refuse to fetch DTDs or entities over network
      --warnnet warn against fetching over the network
      --catalogs : use the catalogs from $SGML_CATALOG_FILES
      --xinclude : do XInclude processing on document input
      --profile or --norman : dump profiling information 
orchis:~ ->

DocBook

The duck picture

DocBook is an XML/SGML vocabulary particularly well suited to books and papers about computer hardware and software.

xsltproc and libxslt are not specifically dependant on DocBook, but since a lot of people use xsltproc and libxml2 for DocBook formatting, here are a few pointers and information which may be helpful:

Do not use the --docbook option of xsltproc to process XML DocBook documents, this option is only intended to provide some (limited) support of the SGML version of DocBook.

Points which are not DocBook specific but still worth mentionning again:

The programming API

Okay this section is clearly incomplete. But integrating libxslt into your application should be relatively easy. First check the few steps described below, then for more detailed information, look at the generated pages for the API and the source of libxslt/xsltproc.c and the tutorial.

Basically doing an XSLT transformation can be done in a few steps:

  1. configure the parser for XSLT:

    xmlSubstituteEntitiesDefault(1);

    xmlLoadExtDtdDefaultValue = 1;

  2. parse the stylesheet with xsltParseStylesheetFile()
  3. parse the document with xmlParseFile()
  4. apply the stylesheet using xsltApplyStylesheet()
  5. save the result using xsltSaveResultToFile() if needed set xmlIndentTreeOutput to 1

Steps 2,3, and 5 will probably need to be changed depending on you processing needs and environment for example if reading/saving from/to memory, or if you want to apply XInclude processing to the stylesheet or input documents.

Python and bindings

There is a number of language bindings and wrappers available for libxml2, the list below is not exhaustive. Please contact the xml-bindings@gnome.org (archives) in order to get updates to this list or to discuss the specific topic of libxml2 or libxslt wrappers or bindings:

The libxslt Python module depends on the libxml2 Python module.

The distribution includes a set of Python bindings, which are guaranteed to be maintained as part of the library in the future, though the Python interface have not yet reached the completeness of the C API.

Stéphane Bidoul maintains a Windows port of the Python bindings.

Note to people interested in building bindings, the API is formalized as an XML API description file which allows to automate a large part of the Python bindings, this includes function descriptions, enums, structures, typedefs, etc... The Python script used to build the bindings is python/generator.py in the source distribution.

To install the Python bindings there are 2 options:

The distribution includes a set of examples and regression tests for the python bindings in the python/tests directory. Here are some excepts from those tests:

basic.py:

This is a basic test of XSLT interfaces: loading a stylesheet and a document, transforming the document and saving the result.

import libxml2
import libxslt

styledoc = libxml2.parseFile("test.xsl")
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseFile("test.xml")
result = style.applyStylesheet(doc, None)
style.saveResultToFilename("foo", result, 0)
style.freeStylesheet()
doc.freeDoc()
result.freeDoc()

The Python module is called libxslt, you will also need the libxml2 module for the operations on XML trees. Let's have a look at the objects manipulated in that example and how is the processing done:

Also note the need to explicitely deallocate documents with freeDoc() except for the stylesheet document which is freed when its compiled form is garbage collected.

extfunc.py:

This one is a far more complex test. It shows how to modify the behaviour of an XSLT transformation by passing parameters and how to extend the XSLT engine with functions defined in python:

import libxml2
import libxslt
import string

nodeName = None
def f(ctx, str):
    global nodeName

    #
    # Small check to verify the context is correcly accessed
    #
    try:
        pctxt = libxslt.xpathParserContext(_obj=ctx)
        ctxt = pctxt.context()
        tctxt = ctxt.transformContext()
        nodeName = tctxt.insertNode().name
    except:
        pass

    return string.upper(str)

libxslt.registerExtModuleFunction("foo", "http://example.com/foo", f)

This code defines and register an extension function. Note that the function can be bound to any name (foo) and how the binding is also associated to a namespace name "http://example.com/foo". From an XSLT point of view the function just returns an upper case version of the string passed as a parameter. But the first part of the function also read some contextual information from the current XSLT processing environement, in that case it looks for the current insertion node in the resulting output (either the resulting document or the Result Value Tree being generated), and saves it to a global variable for checking that the access actually worked.

For more information on the xpathParserContext and transformContext objects check the libray internals description. The pctxt is actually an object from a class derived from the libxml2.xpathParserContext() with just a couple more properties including the possibility to look up the XSLT transformation context from the XPath context.

styledoc = libxml2.parseDoc("""
<xsl:stylesheet version='1.0'
  xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
  xmlns:foo='http://example.com/foo'
  xsl:exclude-result-prefixes='foo'>

  <xsl:param name='bar'>failure</xsl:param>
  <xsl:template match