Chapter 4. Publishing DocBook Documents

$Revision$

Creating and validating XML documents is usually only half the battle. After you’ve composed your document, you’ll want to publish it. Publishing, for our purposes, means either print or web publishing. For XML documents, this is usually accomplished with some kind of stylesheet. In some environments, it is now possible to publish an XML document on the Web simply by putting it online with a stylesheet.

1. A Survey of Stylesheet Languages

Over the years, a number of attempts have been made to produce a standard stylesheet language and, failing that, a large number of proprietary languages have been developed. Since this book was first written, three standards have emerged as the clear frontrunners:

CSS

The W3C CSS Working Group created CSS as a style attachment language for HTML. It has also been advanced as a stylesheet language for XML. Some browsers will style arbitrary XML with CSS and some commercial products exist that will render XML+CSS either online or in print.

XSL

XSLT 1.0 is well established and is probably the most common styling technology for DocBook. XSLT 2.0 offers a number of important new features (at the expense of some complexity, naturally) and is growing in popularity.

It’s worth observing that there are two, related technologies in play here. XSLT 1.0 and 2.0, the transformation languages, and XSL Formatting Objects (XSL-FO). XSL-FO is an XML vocabulary for describing constraints on page layout.

XQuery

XQuery 1.0, developed in parallel with XPath 2.0, provides a different set of features than XSL, but can be used to transform DocBook into other formats.

1.1. Stylesheet Examples

By way of comparison, here’s an example of each of the standard style languages. In each case, the stylesheet fragment shown contains the rules that reasonably formatted the following paragraph:

<para>This is an example paragraph. It should be presented in a
reasonable body font. <emphasis>Emphasized</emphasis> words
should be printed in italics. A single level of 
<emphasis>Nested <emphasis>emphasis</emphasis> should also
be supported.</emphasis>
</para>

1.1.1. CSS stylesheet

CSS stylesheets consist of selectors and formatting properties, as shown in Example 4.1, “A fragment of a CSS stylesheet”.

Example 4.1. A fragment of a CSS stylesheet
@namespace "http://docbook.org/ns/docbook"

para              { display: block }
emphasis          { display: inline;
                    font-style: italic; }
emphasis emphasis { display: inline;
                    font-style: normal; }

As this edition is being written, namespace selection in CSS, while widely supported, is still a Candidate Recommendation at W3C.

1.1.2. XSL stylesheet

XSL stylesheets are XML documents, as shown in Example 4.2, “A fragment of an XSL stylesheet”. The element in the XSL stylesheet that controls the presentation of specific elements is the xsl:template element.

Example 4.2. A fragment of an XSL stylesheet
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                xmlns:db="http://docbook.org/ns/docbook"
                version="1.0">

<xsl:template match="db:para">   
  <fo:block>
    <xsl:apply-templates/>  
  </fo:block>
</xsl:template>  

<xsl:template match="db:emphasis">
  <fo:inline font-style="italic">
    <xsl:apply-templates/>  
  </fo:inline>
</xsl:template>  

<xsl:template match="db:emphasis/db:emphasis">
  <fo:inline font-style="normal">
    <xsl:apply-templates/>  
  </fo:inline>
</xsl:template>  

</xsl:stylesheet>

A complete stylesheet for generating an entire XSL-FO document would require additional boilerplate text not shown.

1.1.3. XQuery

XQuery is expressed in a mixture of text and XML fragments, as shown in Example 4.3, “A fragment of XQuery”.

Example 4.3. A fragment of XQuery
xquery version "1.0";

declare default function namespace "http://www.w3.org/2005/xpath-functions";

declare namespace db="http://docbook.org/ns/docbook";
declare namespace fo="http://www.w3.org/1999/XSL/Format";

declare function local:convert($node as node()) as node()* {
  if (empty($node))
  then
    ()
  else
    typeswitch ($node)
      case text() return $node
      case document-node() return local:convert($node/node())
      case element(db:para) return local:para($node)
      case element(db:emphasis) return local:emphasis($node)
      default return ("ERROR: UNEXPECTED NODE", local:convert($node/node()))
};

declare function local:para($node as element()) as element() {
  <fo:block>
    { local:convert($node/node()) }
  </fo:block>
};

declare function local:emphasis($node as element()) as element() {
  if ($node/parent::db:emphasis)
  then
    <fo:inline font-style="normal">
      { local:convert($node/node()) }
    </fo:inline>
  else
    <fo:inline font-style="italic">
      { local:convert($node/node()) }
    </fo:inline>
};

A complete query for generating an XSL-FO document would require additional boilerplate text not shown.

2. Using XSL to Publish DocBook Documents

The community of people using DocBook has created a set of open source XSL stylesheets that are maintained at Sourceforge.net. These stylesheets can be used to transform DocBook XML into a wide variety of formats, including HTML, Javahelp, XSL-FO (for processing into print), ePub, and HTML help.

For a detailed discussion of using XSL to publish DocBook documents, see DocBook XSL: The Complete Guide [Stayton07].