You have a big DocBook document and you need to extract one
structural element like a chapter
, appendix
etc. to edit or process it separately from the main document.
To make the solution work, the structural element needs an ID attribute. If this is available, use the following stylesheet:
Pass the rootid
parameter to your XSLT
processor with the corresponding ID, for example:
xsltproc --stringparam rootid intro rootid.xsl XML_FILE
The result contains only the element with the corresponding ID value and everything inside it.
This solution cuts off the element with the corresponding ID
and copies the element itself and its children to the output
stream. The copying is done in the process.root
mode. The stylesheet does not apply any further processing. This can be a
disadvantage, for example, a xref
pointing outside of
the respective element. If the resulting file contains such a
cross-reference, it will not be valid anymore.
It is possible to convert such cross-references into a “resolved form” by using the following code:
The stylesheet in Example 3.9, “rootid-resolve-xrefs.xsl
” imports the
rootid.xsl
and inherits all templates. To
implement a different behaviour we need to add a new template
matching for the xref
element in mode
process.root
.
The template contains mostly code from the DocBook XSL stylesheets with some minor changes. The general behaviour is described in the following sequence:
Make sure, everything is in place and a xlink:href
attribute does not contain
a ://
string. If this is the case emit an
error message.
Populate the variables xlink.targets
and linkend.targets
with the target node.
For xlink.targets
use the XLink attribute xlink:href
, for the variable
linkend.targets
use the linkend
attribute. As only one of these attributes can be available,
but not both, the variables are filled with zero nodes or
more.
Create the set union of the variables
xlink.targets
and
linkend.targets
and select only one node.
Now it gets interesting: our context node is in
xref
. We need to know the node where the value
of the xml:id
attribute equals
our rootid
parameter. We climb up tree
with the ancestor-or-self
axis specifier
and select every DocBook element. With the predicate
[@xml:id = $rootid] the node set is
filtered and only those element(s) are preserved where this
expression is true. Only one node from the node set is
selected.
This is done also for the target node and the result is
saved in the variable target.div
The two node from the previous operation are compared
through the generate-id
function. That
leaves two options:
Both nodes are equal. The xref
points somewhere inside the tree
under the rootid
element. That
means, we can copy the xref
element.
Both nodes are not equal. The xref
points outside of the
rootid
element. That means, you
need to “resolve” the xref
element to prevent validation errors.
If the xref
needs to be revamped, we use the
phrase
element, copy all attributes (except linkend
and xlink:href
), and copy anything inside the title of
the target node. As the target node could not be a title
itself, we use again the ancestor-or-self
axis to climb up the tree and select the first emerging
title.
TODO: Add graphic to illustrate the method
Section 3.5, “Splitting DocBook Documents” uses a different approach without needing an ID attribute.
Project@GitHub | Issue#8 |