Guidelines for writing XProc, XSLT, XPath…


  • Use UTF-8 encoding

  • Use soft-tabs with a two space indent

  • Keep lines shorter than 128 characters

  • Use spaces around operators, after commas, colons and semicolons

  • Leave a blank newline at the end of each file

  • Comment your code extensively and use always speaking variable names.


SVN Externals / Git Submodules

  • Always include SVN externals or Git submodules at the root of your repository.

  • Use SVN externals or Git submodules only in your frontend project and not in libraries.

XML Catalogs

  • Include an XML catalog to your repository. The path of your catalog should be xmlcatalog/catalog.xml

  • The catalog file must include a rewriteURI statement which identifies the repository with a URI.

    <?xml version="1.0" encoding="UTF-8"?>
    <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
      <rewriteURI uriStartString="" 


The code should be stored separated by code language. The directory name identifies the typical file extension of the code file. Always use common file extensions, such as xpl for XProc pipelines and xsl for XSLT Stylesheets.

  |  |--stylesheet.css
  |  |--catalog.xml
  |  |--myproject.xpl
  |  |--myproject.xsl


  • Encapsulate commonly used functionality into components with p:import and p:declare-step. Add name and type attributes to each p:declare-step to make it accessible from inside and outside of the pipeline

  • Avoid too many nested p:choose if possible. A proper XSLT is many times a better option to encapsulate application logic.

  • Use p:documentation tags to explain what your pipeline does.

  • Provide debugging features and console output in your pipeline, e.g. via tr:store-debug or cx:message

  • We encourage you to use the cx:depends-on attribute for declaring step order explicitely. This is needed when you want to use steps which operate with files.


  • Avoid too many nested xsl:choose as this will make your code difficult to decipher. Try to replace with xsl:template with concrete matching patterns.

  • Provide a data type for variables via as attribute.

    <xsl:variable name="chapter" select="chapter" as="element(chapter)"/>
  • Avoid to call named templates which call named templates and so on. If applicable use functions instead.

  • Use XSLT modes only if technically required and not to separate your code logically. Be careful when using XSLT modes accompanied with identity templates as this will cost memory and reduce overall execution speed

  • Use namespace and prefix tr for custom functions.


  • Some XPath expressions force the XML parser to perform deep explorations of the XML tree. If you know the expected context, you can reduce CPU and memory usage by avoiding wildcard patterns (*, @*) and deep XPath axis requests (ancestor, descendant or //*, preceding, following).

  • If possible, substitute regular expression functions (matches(), replace(), tokenize()) with simple string manipulation functions (contains(), starts-with(), ends-with(), substring-before(), substring-after(), translate()

  • Indent longer conditional statements, loops and nested functions

    <xsl:value-of select="if(foo)
                          then foo
                          else if (bar)
                               then bar 
                               else false()"/>
  • Comment longer XPath statements: (: my XPath comment :)


Use ➼ Salami Slice Design pattern for writing Schemas


Yo mama use a DTD for her CD catalog.