You need a method to split your document into several “modules” and put it together afterwards.
Use XInclude. It is a W3C
specification and defines the elements xi:include
and
xi:fallback
. They are not DocBook elements (as they
are defined by the W3C and not OASIS), however
they have been integrated in version 5.x[3]. Note, XIncludes work in DocBook regardless which
version (4.x or 5.x) you use.
If you want to use XIncludes, you need these things:
An XML parser that supports XIncludes.
The XInclude namespace http://www.w3.org/2001/XInclude
, usually bound to
the xi
prefix.
The element xi:include
. In general, it can be placed anywhere you
can place DocBook elements. It is a placeholder for the real content and works as a
reference.
The attribute href
inside the
<xi:include>
start tag. It is a URI that refers to
your included file.
The file that is referenced by the href
attribute. The content of the
file will replace the xi:include
element. It
usually contains a DocBook element.
The following example shows a book that points to a substructure assuming chapters:
The above book contains an introduction (file
intro.xml
) and a conceptual overview (file
conceptual-overview.xml
). Both are
referenced by the XInclude´s href
attribute.
Before you transform your document, you need to resolve your XIncludes first, either by your XML parser or “manually” by an XSLT transformation. The following procedure shows a typical workflow:
The previous procedure showed a book with xincluded chapters. It is possible to even go deeper and also include a section into a chapter. Actually, there is no limit. You should only be aware that you do not create circular references (file A includes file B and B includes A).
As XIncludes are very common nowadays, resolving
xi:include
and transforming into the output format
can be done in one step. This is the case for most tools:
Use the --xinclude
option as shown:
xsltproc --xincludeSTYLESHEET
XMLFILE
Unfortunately, Saxon 6 needs some more configuration. Most Linux distribution already have a saxon6 command. However, it can be difficult to correctly customize it, so this is the line you need:
java -Dorg.apache.xerces.xni.parser.XMLParserConfiguration=org.apache.xerces.parsers.XIncludeParserConfiguration \JARPATH
/saxon6.jar:JARPATH
/xml-commons-apis.jar:JARPATH
/jaxp_parser_impl.jar:JARPATH
/xml-commons-resolver.jar \ com.icl.saxon.StyleSheet \ -x org.apache.xml.resolver.tools.ResolvingXMLReader \ -y org.apache.xml.resolver.tools.ResolvingXMLReader \ -r org.apache.xml.resolver.tools.CatalogResolver\ARGS
The line contains different properties:
The org.apache.xerces.xni.parser.XMLParserConfiguration property sets the XInclude processor which is done by Xerces in this case.
The JARPATH
is the path to your
JAR files. In most FHS conformant Linux distributions,
nowadays this is usually /usr/share/java
.
Additionally, with the xml-commons-resolver.jar
file, Saxon 6 is able to resolve catalogs. To tell Saxon
you need to set the -r
, -x
,
and -y
options the URI resolver class, and
the specified Sax parser for source file and stylesheet.
ARGS
are the specific
arguments for Saxon and contain source document and stylesheet.
To list all available options, use -h
.
Version 9 contains the -xi
option to resolve
XIncludes (assuming you have a script saxon9
that does all the heavy Java lifting):
saxon9 -xi -xsl:STYLESHEET
-s:XMLFILE
The last section showed a general method to work with XIncludes. In most cases this is enough. However, XIncludes offers more benefits that are discovered in the following subsections.
If the referenced file in the xi:include
element
is not available, the XInclude step will fail. How can you avoid
that? The XInclude specification also defines the
xi:fallback
element. This element can be used to
add code when a referenced resource could not be retrieved:
The previous code does the following: When the
xi:include
element is being processed, the XML
parser tries to include the file
revhistory.xml
. If the file can not be
retrieved, the XML parser will consider the xi:fallback
element
and include its contents. In the above case it includes a
para
element showing the failed attempt.
This method is useful when you want to process files that might not permanently be available. For example, the previous revision history needs to be generated first. However, it is not always sure that the revision history can be generated from an possible offline version control system.
The previous examples dealt with included resources in XML only. If you need to include text, this can also be done with XInclude.
The most common use-case is including source code that is maintained separately. The following example points to C source code that needs to be included as text:
The important line is parse="text"
. This
advises the XInclude processor to handle the referenced file
as text and not as XML. The default value for parse
is xml
.
It is recommended to remove any whitespaces inside
programlisting
as shown above to avoid spurious
indendation or linebreaks.
More explanations can be found in Section 1.8, “Incorporating External Files in Code Listings”.
[3] To use XInclude with DocBook 5.x, use the
docbookxi.rnc
RELAX NG schema.
Project@GitHub | Issue#6 |