DocBook

Description DocBook is a set of tags used to describe the logical structure of the content of your articles or books. For example, writing an article using DocBook would look like the following:

<article>
<title>My article's title</title>
</article>

Content written in DocBook can then later be published in different format such as HTML, PDF, RTF.

Apache FOP java.lang.OutOfMemoryError with fop Add -Xmx128m in the last line of fop.bat as follows:

"%JAVACMD%" -Xmx128m %JAVAOPTS% %LOGCHOICE% %LOGLEVEL% -cp "%LOCALCLASSPATH%" org.apache.fop.cli.Main %FOP_CMD_LINE_ARGS%

PDF Bookmarks To generate PDF bookmarks use <xsl:param name="fop.extensions" select="1"></xsl:param> if you use FOP version 0.20.5 and earlier. Otherwise, use <xsl:param name="fop1.extensions" select="1"></xsl:param>

DocBook: The Definitive Guide http://www.docbook.org/tdg/en/html/docbook.html

DocBook Roundtripping(How to convert DocBook to WordML and vice versa) http://www.explain.com.au/oss/docbook/

DocBook XSL Stylesheets: Reference Documentation http://docbook.sourceforge.net/release/xsl/current/doc/index.html

DocBook Element tags Reference http://www.docbook.org/tdg/en/html/part2.html

DocBook 4.3 Quick Reference: http://www.nmt.edu/tcc/help/pubs/docbref/docbref.pdf

DocBook XSL: The Complete Guide http://www.sagehill.net/docbookxsl/

Tutorial using XMLmind http://www.xml.com/pub/a/2007/06/20/getting-productive-with-xmlmind.html?page=last

Caching in with Resolvers http://nwalsh.com/docs/articles/xml2003/

Writing DocBook with LyX: http://www.neomantic.com/tutorials/lyx-and-docbookXML

DocBook Diff(DiffMk, XOP): http://dojotoolkit.org/pipermail/dojo-interest/2007-December/030811.html http://sourceforge.net/project/showfiles.php?group_id=46101 http://www.living-pages.de/de/projects/xop/

Setup DocBook with Eclipse http://www.vogella.com/articles/DocBook/article.html

Add Date and Time

There are 2 ways to insert date and time.

Insert date and time using processing instruction

Here is an example in my Docbook file:

<pubdate><?dbtimestamp format="B d, Y at H:M:S"?></pubdate>
<!--Will generate: April 12, 2008 at 16:17:53-->
<!--More on format string can be found at http://www.sagehill.net/docbookxsl/Datetime.html -->

Insert date and time in the customization layer

  1. Add a marker inside your docbook. In my example, I assign my marker now to the role attribute:
    <pubdate role="now"></pubdate>
  2. In my customization layer, I'm using the EXSLT date-time() function supported by xsltprocprocessor. Here is what I put in my customization layer:
    <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet version="1.0" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:fo="http://www.w3.org/1999/XSL/Format"
        xmlns:date="http://exslt.org/dates-and-times"> <!-- This declaration is needed in order to be able to use date and time function. -->
     
      <!-- Note the xmlns:date="..." above -->
      <xsl:template match="pubdate[@role='now']" mode="titlepage.mode">
        <xsl:variable name="now" select="date:date-time()"/>
        <fo:block>
          <xsl:text>Generated on </xsl:text>
          <!-- Month name -->
          <xsl:value-of select="date:month-name($now)"/>
          <xsl:text> </xsl:text>
     
          <!-- Day in month -->
          <xsl:call-template name="TimeDigits">
          <xsl:with-param name="iTime" select="date:day-in-month($now)"/>
          </xsl:call-template>
          <xsl:text>, </xsl:text>
     
          <!-- Year -->
          <xsl:value-of select="date:year($now)"/>
          <xsl:text> at </xsl:text>
     
          <!-- Hour -->
          <xsl:call-template name="TimeDigits">
          <xsl:with-param name="iTime" select="date:hour-in-day($now)"/>
          </xsl:call-template>
          <xsl:text>:</xsl:text>
     
          <!-- Minute -->
          <xsl:call-template name="TimeDigits">
          <xsl:with-param name="iTime" select="date:minute-in-hour($now)"/>
          </xsl:call-template>
          <xsl:text>:</xsl:text>
     
          <!-- Second -->
          <xsl:call-template name="TimeDigits">
          <xsl:with-param name="iTime" select="date:second-in-minute($now)"/>
          </xsl:call-template>
        </fo:block>
      </xsl:template>    
     
      <!-- Pad 0 to digit < 10 -->
      <xsl:template name="TimeDigits">
        <xsl:param name="iTime"/>
        <xsl:choose>
          <xsl:when test="$iTime &lt; 10"><xsl:value-of select="concat('0',$iTime)"/></xsl:when>
          <xsl:otherwise><xsl:value-of select="$iTime"/></xsl:otherwise>
        </xsl:choose>
      </xsl:template>
    </xsl:stylesheet>

Reference

http://www.sagehill.net/docbookxsl/Datetime.html

Adding <?lb?> processing instruction as line break

FO customization:

<xsl:template match="processing-instruction('lb')">
  <fo:block/>
</xsl:template> 

HTML customization:

<xsl:template match="processing-instruction('lb')">
  <br />
</xsl:template> 

Adding special characters using different fonts

Adding special characters using different fonts To add a special character using a specific font, you have to do the followings. For example, if you want to add a check symbol, you have to add the following in your docbook file.

<!-- Insert the check symbol -->
<symbol role="ZapfDingbats">&check;</symbol><!-- in named entity -->
<symbol role="ZapfDingbats">&#x2713;</symbol><!-- in hexadecimal  -->
<symbol role="ZapfDingbats">&#8658;</symbol><!-- in decimal -->

In your customization layer, you tell docbook to use ZapfDingbats font-family for symbol element with ZapfDingbats role as follows:

<xsl:template match="symbol[@role = 'ZapfDingbats']">
  <fo:inline font-family="ZapfDingbats">
    <xsl:apply-templates/>
  </fo:inline>
</xsl:template>

With this process, you can add as many fonts as you want by simply using different role attributes.

References

Customizations - FO

Page setup http://www.sagehill.net/docbookxsl/PrintOutput.html#TopBotMargins http://docbook.sourceforge.net/release/xsl/current/doc/fo/general.html

Font size Font size throughout the document:

<xsl:param name="body.font.master">10</xsl:param>

References

Customizations - HTML

Numbering the table of content(TOC)

To number the table of content(TOC) so that looks like this:

1.  Chapter    
1.1  Section
1.2  Section          
1.2.1 Section        
2.  Chapter              
2.1  Section
2.2  Section


Add the following in your customization.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 
  <xsl:import href="lib/docbook-xsl/html/docbook.xsl"/>
 
  <xsl:param name="generate.toc">
    appendix  toc,title
    article/appendix  nop
    article   toc,title
    book      toc,title,figure,table,example,equation
    chapter   title
    part      title
    preface   title
    qandadiv  toc
    qandaset  toc
    reference toc,title
    sect1     toc
    sect2     toc
    sect3     toc
    sect4     toc
    sect5     toc
    section   toc
    set       toc,title
  </xsl:param>
  <xsl:param name="section.autolabel" select="1"></xsl:param>
  <xsl:param name="section.label.includes.component.label" select="1"></xsl:param>
 
</xsl:stylesheet>

Set Cascading Style Sheets(css) path in your html file

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 
  <xsl:import href="lib/docbook-xsl/html/docbook.xsl"/>
 
  <!--
    The path of the Cascading Style Sheets(css) that will be set in the <link> tag of your HTML output file.
  -->
  <xsl:param name="html.stylesheet">css/doc.style.css</xsl:param>
 
</xsl:stylesheet>
AttachmentSize
File doc.style_.css655 bytes

Customize GUI elements

For FO customization:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format" 
  version="1.0">
 
  <!-- Make <guibutton> looks like a button. -->
  <xsl:template match="guibutton">
    <fo:inline border="1px outset #dddddd"
               background-color="#dddddd">
      <xsl:call-template name="inline.charseq"/>
    </fo:inline>
  </xsl:template>
 
</xsl:stylesheet>


For HTML customization, include the following in the Cascading Style Sheets(CSS)

.guilabel
{
  font-weight: bold;
}
 
.guibutton
{
  border: 2px outset #dddddd;
  background-color: #dddddd;
}

Docbook predefined special characters

CharacterNamed entityDescription
&trade; Trade mark
©&copy; Copyright
®&reg; Registered
±&plusmn;Plus or minus
&check; Check mark
&cross; Ballot X
&uarr; Up arrow
&darr; Down arrow
&larr; Left arrow
&rarr; Right arrow
&harr; Left right arrow

Reference: http://www.oasis-open.org/docbook/documentation/reference/html/refchar.html

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book SYSTEM "lib/docbook-xml/docbookx.dtd">
<book>
  <chapter>
    <title>Tutorial: Docbook predefined special characters</title>
      <table><title>Docbook predefined special characters</title>
        <tgroup cols="3">
          <thead>
            <row><entry>Character</entry><entry>Named entity</entry><entry>Hexadecimal</entry><entry>Description</entry></row>
          </thead>
          <tbody>
            <row><entry>&trade; </entry><entry><![CDATA[&trade; ]]></entry><entry><![CDATA[&#x02122;]]></entry><entry>Trade mark</entry></row>
            <row><entry>&copy;  </entry><entry><![CDATA[&copy;  ]]></entry><entry><![CDATA[&#x000A9;]]></entry><entry>Copyright</entry></row>
            <row><entry>&reg;   </entry><entry><![CDATA[&reg;   ]]></entry><entry><![CDATA[&#x000AE;]]></entry><entry>Registered</entry></row>
            <row><entry>&plusmn;</entry><entry><![CDATA[&plusmn;]]></entry><entry><![CDATA[&#x000B1;]]></entry><entry>Plus or minus</entry></row>
            <row><entry>&check; </entry><entry><![CDATA[&check; ]]></entry><entry><![CDATA[&#x02713;]]></entry><entry>Check mark</entry></row>
            <row><entry>&cross; </entry><entry><![CDATA[&cross; ]]></entry><entry><![CDATA[&#x02717;]]></entry><entry>Ballot X</entry></row>
            <row><entry>&uarr;  </entry><entry><![CDATA[&uarr;  ]]></entry><entry><![CDATA[&#x02191;]]></entry><entry>Up arrow</entry></row>
            <row><entry>&darr;  </entry><entry><![CDATA[&darr;  ]]></entry><entry><![CDATA[&#x02193;]]></entry><entry>Down arrow</entry></row>
            <row><entry>&larr;  </entry><entry><![CDATA[&larr;  ]]></entry><entry><![CDATA[&#x02190;]]></entry><entry>Left arrow</entry></row>
            <row><entry>&rarr;  </entry><entry><![CDATA[&rarr;  ]]></entry><entry><![CDATA[&#x02192;]]></entry><entry>Right arrow</entry></row>
            <row><entry>&harr;  </entry><entry><![CDATA[&harr;  ]]></entry><entry><![CDATA[&#x02194;]]></entry><entry>Left right arrow</entry></row>
 
          </tbody>
        </tgroup>
      </table>
  </chapter>
</book>

Elements that are good to know

Element Description
literallayout A block of text in which line breaks and white space are to be reproduced faithfully.
acronym For an acronym such as XML.
application Name of an application such as MS Word.
citetitle Title of a book, film, musical work, etc.
filename File names
computeroutput Computer output. Every characters are monospaced.
userinput For things a user types.
guibutton Name of a button in a graphical user interface.
guiicon Name of an icon in a graphical user interface.
guilabel Name of a label in a graphical user interface.
guimenu Name of a menu in a graphical user interface.
<procedure>
  <step>
  <para>...</para>
  </step>
  ...
</procedure>
If you add id='S' attribute to a given step, you can refer to that step elsewhere using <xref linkend='S'/>.
<variablelist>
  <varlistentry>
    <term>term</term>
    <listitem>
      <para>definition</para>
    </listitem>
  </varlistentry>
  ...
</variablelist>
List of terms and their definitions.
<menuchoice>
  <guimenu>File</guimenu>
  <guimenuitem>Save</guimenuitem>
</menuchoice>
File->Save

http://www.ibiblio.org/godoy/sgml/docbook/howto/writing-docbook.html http://www.docbook.org/docs/transclusion/

Generate another version of DocBook for your customer

Sometimes you want to generate a different version of your docbook for your customer. In my case, I was using the common attribute role to mark the content that I don't want the customer to see. Therefore, I set role="NotForClient" on all nodes that I don't want my customer to see. Then, I apply an XSL stylesheet to remove those nodes.

Here is the XSL stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <!-- Copy everything -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <!-- 
  In order to remove all nodes that has the attribute role="NotForClient",
  write a template as below to catch all nodes with @role='NotForClient' and do nothing.
  Therefore, the node is removed.
  -->
  <xsl:template match="*[@role='NotForClient']" />
 
</xsl:stylesheet>

Image Scaling

To keep a graphic for printed output at its natural size unless it is too large to fit the available width, in which case shrink it to fit, use scalefit="1", width="100%", and contentdepth="100%" attributes.

Install xsltproc and FOP to generate a PDF from a docbook document

Install xsltproc

  1. Go here to download iconv, zlib, libxml2 and libxslt.
  2. Decompress all the files downloaded.
  3. Put the folder path of iconv.exe, libxml2.dll, xsltproc.exe and zlib1.dll in the environment variable PATH.
  4. Open Command Prompt and run xsltproc.exe. It should show something similar to the following:
    C:\>xsltproc -version
    Using libxml 20630, libxslt 10122 and libexslt 813
    xsltproc was compiled against libxml 20630, libxslt 10122 and libexslt 813
    libxslt 10122 was compiled against libxml 20630
    libexslt 813 was compiled against libxml 20630  
     

Install Apache FOP

  1. Go here to download fop (e.g. fop-0.95-bin.zip).
  2. Decompress fop (e.g. fop-0.95-bin.zip).
  3. Put the folder path of fop.bat in environment variable PATH.
  4. Open Command Prompt and run fop.bat. It should show something similar to the following:
    C:\gpl\docbook\fop-0.95>fop -v
    FOP Version 0.95
    ...
     

Generate your first PDF docbook

  1. Go here to download the latest version of docbook-xsl (e.g. docbook-xsl-1.75.2.zip).
  2. Decompress docbook-xsl downloaded.
  3. Download MyFirstDocbook.xml, a sample docbook file.
  4. Open Command Prompt and run the following commands(Note:Change the paths accordingly):
    C:\>xsltproc X:\path_to_docbook-xsl_folder\fo\docbook.xsl X:\path_to\MyFirstDocbook.xml > MyFirstDocbook.fo
    C:\>fop MyFirstDocbook.fo MyFirstDocbook.pdf
     

Locally fetching DOCTYPE

Pointing DOCTYPE to directly use local copies

<!-- Pointing DOCTYPE to use C:\gpl\tools\docbook-xml-4.5\docbookx.dtd -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "file:///C:/gpl/tools/docbook-xml-4.5/docbookx.dtd">

Using this method is not efficient as you will have to change all your files containing DOCTYPE if the path had changed. A better way is to use XML catalog.

Using XML catalog When you use XML catalog, you don't have to change anything on your files. You only have to create the XML catalog file and tell the XSL processor to use it.

  1. Create the XML catalog. Here is an example:
    <?xml version='1.0'?>
    <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
        <!-- All "-//OASIS//DTD DocBook XML V4.5//EN" will use E:\gpl\tools\docbook-xml-4.5\docbookx.dtd instead of the 1 that is defined in you file. -->
        <public publicId="-//OASIS//DTD DocBook XML V4.5//EN" uri="file:///E:/gpl/tools/docbook-xml-4.5/docbookx.dtd"/>
    </catalog>
  2. Tell your XSL processor to use your XML catalog file. Here is an example:
    REM xsltproc will look for XML_CATALOG_FILES environment variable in order to know where is the XML catalog file.
    SET XML_CATALOG_FILES=E:\Projects\test\Catalog.xml
    xsltproc --nonet E:\gpl\tools\docbook-xsl\fo\docbook.xsl myBook.xml > myBook.fo
    call fop -fo myBook.fo -pdf myBook.pdf
    SET XML_CATALOG_FILES=&::

References http://nwalsh.com/docs/articles/xml2003/

Page Setup

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
 
    <!-- Output characteristics. Note: string value has to be put between single quote. -->
    <xsl:param name="paper.type" select="'A4'"/> <!-- standard paper size -->
    <xsl:param name="draft.mode"  select="'yes'"/><!-- yes = draft -->
    <xsl:param name="draft.watermark.image" select="concat($DocBookRootDir,'images/draft.png')"/>
    <xsl:param name="page.orientation" select="'landscape'"/>
 
    <!-- Page margin spacing -->
    <xsl:variable name="SpacingWidth">0.1in</xsl:variable>
    <xsl:param name= "page.margin.top"><xsl:value-of select="$SpacingWidth"/></xsl:param>
    <xsl:param name= "page.margin.bottom"><xsl:value-of select="$SpacingWidth"/></xsl:param>
    <xsl:param name="page.margin.inner">
        <xsl:choose>
            <xsl:when test="$double.sided != 0"><xsl:value-of select="$SpacingWidth"/></xsl:when>
            <xsl:otherwise><xsl:value-of select="$SpacingWidth"/></xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="page.margin.outer">
        <xsl:choose>
            <xsl:when test="$double.sided != 0"><xsl:value-of select="$SpacingWidth"/></xsl:when>
            <xsl:otherwise><xsl:value-of select="$SpacingWidth"/></xsl:otherwise>
        </xsl:choose>
    </xsl:param>
 
<!-- Doesn't work yet.
<xsl:param name="page.width">
  <xsl:choose>
      <xsl:when test="$page.orientation = 'portrait'">
          <xsl:value-of select="$page.width.portrait"></xsl:value-of>
      </xsl:when>
      <xsl:otherwise>
          <xsl:value-of select="$page.height.portrait"></xsl:value-of>
      </xsl:otherwise>
  </xsl:choose>
</xsl:param>
-->
 
</xsl:stylesheet>

Page Layout http://www.sagehill.net/docbookxsl/PrintOutput.html#TopBotMargins

Split into multiple docbook files

The best way to handle big documentation is to break it into multiple files. Docbook allows you to do that by using XInclude. Here is how it is done.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Here is the master file called book.xml -->
<!-- Note the word 'book' after DOCTYPE below.-->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<book>
  <title>My Docbook Title</title>
  <!-- Include intro chapter from external file, intro.xml -->
  <xi:include href="intro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
</book>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Here is the intro.xml file to be include inside book.xml -->
<!-- Note the word 'chapter' after DOCTYPE below.-->
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" 
  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="intro">
    <title>Intro</title>
    <para>Imported chapter.</para>
</chapter>

To validate the files, you can use xmllint --noout --xinclude --postvalid --noent book.xml. To create the PDF for your whole document, run

xsltproc --xinclude /path/to/your/docbook-xsl/fo/docbook.xsl book.xml > book.fo
fop -fo book.fo -pdf book.pdf

For more details, see http://www.sagehill.net/docbookxsl/ModularDoc.html.

Table

Long table

<!-- Long table that can't be fit into 1 page will be broken down to span across multiple pages -->
<!-- More info can be found at http://www.sagehill.net/docbookxsl/PageBreaking.html#KeepTogetherPI -->
<xsl:attribute-set name="formal.object.properties">
  <xsl:attribute name="keep-together.within-column">auto</xsl:attribute>
</xsl:attribute-set>

Format table headers

<!-- Header rows have blue background and white character color-->
<xsl:template name="table.row.properties">
  <xsl:if test="ancestor::thead">
    <xsl:attribute name="font-weight">bold</xsl:attribute>
    <xsl:attribute name="color">#FFFFFF</xsl:attribute><!-- White -->
    <xsl:attribute name="background-color">#0000FF</xsl:attribute><!-- Blue -->
  </xsl:if>
  <xsl:attribute name="text-align">left</xsl:attribute><!-- left, right, justify -->
</xsl:template>
<?xml version="1.0" encoding="UTF-8"?>
<!--
Description: Format table header
Date: 2008-01-17:
Author: Xuan Ngo
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
 
  <!-- Copy everything -->
  <!-- ############# -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <!-- Catching matching conditions -->
  <xsl:template match="thead/row">
    <xsl:element name="row">
      <xsl:processing-instruction name="dbhtml">bgcolor="#000000"</xsl:processing-instruction>
      <xsl:processing-instruction name="dbfo">bgcolor="#000000"</xsl:processing-instruction>
 
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
 
</xsl:stylesheet>


Column width

Add colspec tag inside your xml DocBook file.

<table><title>My table</title>
<tgroup cols="4" >
<colspec colnum="1" colname="col1" colwidth="1*"/>
<colspec colnum="2" colname="col2" colwidth="2*"/>
<colspec colnum="3" colname="col3" colwidth="1.5*"/>
<colspec colnum="4" colname="col4" colwidth="1*"/>
<thead>
...

Here is how you specify column width values: colwidth specifies the desired width of the relevant column. It can be either a fixed measure using one of the CALS units (36pt, 10pc, etc.) or a proportional measure. Proportional measures have the form “number”, meaning this column should be number times wider than a column with the measure “1” (or just “”). These two forms can be mixed, as in “3+1pc”.

Change the background color of the row in a table according to the value of the <entry>

<?xml version="1.0" encoding="UTF-8"?>
<!--
Description: 
  Change the background color of the row in a table according to the value of the <entry>.
  In this case, it will set the background color of the row to red if the value of the last column of the row is No(i.e. <entry>No</entry>).
Note: This is not a customization. It is simply an XSL stylesheet that needs to be applied on your docbook's xml file.
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
 
  <!-- Copy everything -->
  <!-- ############# -->
  <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
 
  <!--
    The core logic start here.
    -Catch all <row>.
    -Check whether the last <entry> is equal to 'No'.
      If it does, reconstruct the <row> element and at the same time, add the processing instruction to set the background color to red.
      Otherwise, reconstruct the <row> element.
  -->
  <xsl:template match="row">
    <xsl:choose>
      <!-- Check whether the last <entry> contains 'No' -->
      <xsl:when test="entry[last() and text()='No']">
        <xsl:element name="row">
          <xsl:apply-templates select="@*|node()"/><!-- Copy everything under <row>, preserve data -->
          <!-- Add the processing instruction to set the background color to red. -->
          <xsl:processing-instruction name="dbhtml">bgcolor="#FF0000"</xsl:processing-instruction>
          <xsl:processing-instruction name="dbfo">bgcolor="#FF0000"</xsl:processing-instruction>
        </xsl:element>
      </xsl:when>
 
      <xsl:otherwise>
        <xsl:element name="row">
          <xsl:apply-templates select="@*|node()"/><!-- Copy everything under <row>, preserve data -->
        </xsl:element>
      </xsl:otherwise>
 
    </xsl:choose>
  </xsl:template>
 
</xsl:stylesheet>

Using Entities to define a shared string

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE book [
  <!ENTITY product-name "Docbook">
  <!ENTITY product-version "4.5">
]>
<book>
  <chapter>
    <title>Tutorial: Using Entities to define a shared string</title>
    <para>The latest version of <application>&product-name;</application> is &product-version;.</para>
    <para><application>&product-name;</application> is best used to write documentation.</para>
  </chapter>
</book>