Processing options

The system of processing documents with olinks has some flexibility to adapt to your particular needs. These are some options that might be useful.

Naming your data files

You can specify the filename and directory of the generated target data file for a document by using the targets.filename parameter. This is useful when you have more than one XML document in the same directory and you need to give them separate data files, or you want to put them in a shared directory.

Using the Saxon example:

java com.icl.saxon.StyleSheet  userguide.xml  docbook.xsl \
      collect.xref.targets="only" \
      targets.filename="../shared/mytargetfile"

Be sure to specify the same filename for that data file when you create your master target database document.

Likewise, you can choose your own filename and location for the master database file using the target.database.document parameter (olinkdb.xml is just a suggested name). This name is used when you want to resolve olinks, so you pass the name to the processor as a command line parameter:

xsltproc  --stringparam  target.database.document  "../shared/olinkdb.xml" \
  docbook.xsl  userguide.xml

A relative path here is taken as relative to the document being processed.

Using Makefiles with olinking

Olinks create dependencies between documents, and Makefiles are good at tracking dependencies. The following is a simple Makefile for one example document. Other documents would have similar Makefiles.

SINGLESTYLE = /tools/xsl/docbook-xsl/docbook.xsl
CHUNKSTYLE = /tools/xsl/docbook-xsl/chunk.xsl

UGOUTPUT = /http/guides/mailuser
AGOUTPUT = /http/guides/mailadmin
REFOUTPUT = /http/reference/mailref

AdminTargets = ../adminguide/target.db
RefTargets = ../man/target.db

html:  $(UGOUTPUT)/userguide.html

$(UGOUTPUT)/userguide.html : userguide.xml target.db  \
                             $(AdminTargets) $(RefTargets)
        java com.icl.saxon.StyleSheet -o $(UGOUTPUT)/userguide.html \
             userguide.xml $(SINGLESTYLE) \
             target.database.document="/projects/mail/olinkdb.xml" 

target.db : userguide.xml
        java com.icl.saxon.StyleSheet userguide.xml $(SINGLESTYLE) \
             collect.xref.targets="only" \
             targets.filename="target.tmp"
        if ! diff target.db target.tmp > /dev/null 2>&1 ; \
             then cp target.tmp target.db; fi
        rm target.tmp
         

In the target.db rule, the target data is saved to a temporary file first. If it differs from the existing target.db file, then it overwrites it. If it does not differ, then the file is not overwritten and its timestamp is left unchanged. Any document changes that do not affect cross reference targets would thus not update the data file. That would prevent unnecessary processing of other documents that have a dependency on its cross reference data.

An alternative to Makefiles is Apache Ant, which is written in Java so it runs on all platforms. It is described at http://ant.apache.org/. For help in using Ant with DocBook, see Dave Pawson's article Docbook and Ant.

Using XInclude in the database document

You can use XInclude instead of system entities in the olinkdb.xml database file. That has the advantage of not needing to declare system entities. An XInclude can just specify a path directly to a data file. You also would not need the DOCTYPE document type declaration and the DTD. But you would need an XSL processor that handles XIncludes. See the section “Processing your modular documents” for more information.

The following is a portion of the example database using XInclude:

<?xml version="1.0"?>
<targetset>
  <targetsetinfo>
    Description of this target database document,
    which is for the examples in olink doc.
  </targetsetinfo>

  <!-- Site map for generating relative paths between documents -->
  <sitemap>
    <dir name="documentation">
      <dir name="guides"> 
        <dir name="mailuser">
          <document targetdoc="MailUserGuide" baseuri="userguide.html">
            <xi:include href="/doc/userguide/target.db"  
                        xmlns:xi="http://www.w3.org/2001/XInclude"/>
          </document>
        </dir>
        ...
     

The path to the data file is in the href attribute. You must also declare the XInclude namespace in each include element.

Using catalogs for olink data

You can use catalog files to find your target data files. Catalog files let you map logical names to actual pathnames on a filesystem. That provides greater flexibility, reduces maintenance, and makes your system more portable, since you can just edit catalog files to make changes in locations. These features become more important when you have cross references between documents because the cross reference data files have to be found by the processor at runtime.

If you use system entities in your target database, then you can simplify that file and let the catalog resolve the actual paths to the target data files. The following is what the top of an olink database might look like:

/projects/mail/olinkdb.xml:
<?xml version="1.0"?>
<!DOCTYPE targetset SYSTEM "targetdatabase.dtd" [
<!ENTITY ugtargets SYSTEM "ugtargets.ent">
<!ENTITY agtargets SYSTEM "agtargets.ent">
<!ENTITY reftargets SYSTEM "reftargets.ent">
]>

The XML catalog file that could resolve those entity paths into actual file pathnames could look like the following:

/tools/catalog.xml:
<?xml version="1.0"?>
<!DOCTYPE catalog
   PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
   "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
  <system systemId="targetdatabase.dtd" 
          uri="file:///tools/docbook-xsl-1.73.1/common/targetdatabase.dtd" />
  <system systemId="ugtargets.ent" 
          uri="file:///doc/userguide/target.db" />
  <system systemId="agtargets.ent" 
          uri="file:///doc/adminguide/target.db" />
  <system systemId="reftargets.ent" 
          uri="file:///doc/man/target.db" />
</catalog>

When the processor reads the olinkdb.xml file, it will use the catalog to resolve the locations of the system entities for each of the target data files. See Chapter 5, XML catalogs for more information about using XML catalog files.

Olinks with profiling (conditional text)

If you use profiling (conditional text), then you must separate your data for the different profiles. You do not want target data in a data file for elements that may be excluded from the current profile. That would lead to olinks that seem to resolve, but that do not actually work in the HTML output.

You need to create a separate data file for each profile a document can be rendered in. You do that by running the collection process with the profile parameters set, and saving the output to a different name by setting the targets.filename parameter. Because the target collection process uses the same stylesheet settings as when you process the document in a given profile, the data will include only elements in that profile. The following is an example of collecting targets while processing for output with a profile:

xsltproc --output unixbook.html \
   --stringparam profile.os "unix" \
   --stringparam targets.filename  "unix.profile.db" \
   --stringparam collect.xref.targets "yes" \
   .../html/profile-docbook.xsl  mybook.xml

This will generate the unixbook.html output and the target data file named unix.profile.db. When you process other documents with olinks for that profile, you need to use this data file to resolve them.

To use profiled data files, you can do it in either of two ways.

  • Set up multiple master database documents, one for each profile. Then you can reference the appropriate profiled data filenames in each database. When you process your documents with olinks, you specify the profiled database with the target.database.document parameter at runtime.

  • Use a single master database document, but remap its references using an XML catalog. You set up a catalog for each profile, and then specify at runtime the correct catalog for a given profile. Each catalog maps whatever the identifier is for a given document in the master database to its appropriate profiled data file. For example, the following entry in a master database:

    <!ENTITY ugtargets SYSTEM "/doc/userguide/target.db"> 

    could be remapped with this entry in a "unix profile" XML catalog:

    <system
       id="/doc/userguide/target.db"
       uri="file:///doc/userguide/unix.profile.db" />

If you have multiple independent profile selectors, it is quite possible the number of permutations is too complex for olinks. You might establish the writing convention that olinks are not to be pointed at targets that have conditional attributes. Point to a higher level container without conditional attributes instead.

Remote olink targets

You can use olinks to link to documents that are available on a website. The only requirement is that you be able to obtain the olink target data for such documents. Then you can set the baseuri attribute to a full path URI that points to the document's path on the website. You can mix remote documents with local documents as well, as this example illustrates:

<document targetdoc="moduleA" baseuri="../doc">
  <xi:include href="moduleA/target.db" ...>
</document>
<document targetdoc="moduleG" baseuri="http://my.website.net/modules">
  <xi:include href="moduleG/target.db" ...>
</document>

When an olink points to targetdoc="moduleA", it will form a local link. When an olink points to targetdoc="moduleG", then it will form a full URL to the website.