試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

DocBook XML文書からXHTML文書への変換

DocBook XML文書をXHTML文書に変換するのは簡単だが、奥の深いカスタマイズもできる。
サンプル文書として、「DocBook文書について」の記事の中の「bookの例」として紹介したファイルをbooktest.xmlとして保存して使用することにする。

DocBook XSLスタイルシートの場所

ディストリによって多少異なる。
Gentoo Linuxでは/usr/share/sgml/docbook/xsl-stylesheets/の下、Debian,Ubuntuでは/usr/share/xml/docbook/stylesheet/nwalsh/以下。
下にあるようなサブディレクトリが含まれている場所になる。

$ ls -F /usr/share/sgml/docbook/xsl-stylesheets-1.70.1/
VERSION   extensions/  htmlhelp/  lib/       profiling/  tools/    xhtml/
common/   fo/          images/    manpages/  slides/     website/
eclipse/  html/        javahelp/  params/    template/   wordml/

基本の形

標準出力として、1つのXHTMLファイルに全てが書き出される。

$ xsltproc [docbook-xslのディレクトリ]/xhtml/docbook.xsl booktest.xml >| booktest.html
もしくは
$ Xalan booktest.xml [docbook-xslのディレクトリ]/xhtml/docbook.xsl >| booktest.html
もしくは
$ java -jar [saxon.jarの場所] booktest.xml [docbook-xslのディレクトリ]/xhtml/docbook.xsl >| booktest.html

ページを分割する

分割するためのXSLスタイルシート

上の例では、スタイルシートxhtml/docbook.xslを使用して1つのXHTMLファイルにしているが、規模が大きくなってくると、それでは都合が悪くなることもあり、セクションごとに(デフォルトではsect1要素単位)ページを分割することもできる。
方法としては、xhtml/docbook.xslの代わりにxhtml/chunk.xslを指定するのだが、例として、xsltprocの場合、下のように指定すると、複数の.htmlファイルが出力される。

$ xsltproc [docbook-xslのディレクトリ]/xhtml/chunk.xsl booktest.xml
Writing pr01.html for preface(preface)
Writing ch01.html for chapter(chap1)
Writing ch02.html for chapter(chap2)
Writing index.html for book

開くのはindex.htmlで分かりやすいのだが、他はファイル名が分かりにくくなってしまう。

$ java -jar [saxon.jarの場所] booktest.xml [docbook-xslのディレクトリ]/xhtml/chunk.xsl
Writing pr01.html for preface(preface)
Writing ch01.html for chapter(chap1)
Writing ch02.html for chapter(chap2)
Writing index.html for book
<?xml version="1.0" encoding="UTF-8"?>

Saxon 6でも通るが、Xalan(C++)では

$ Xalan booktest.xml [docbook-xslのディレクトリ]/xhtml/chunk.xsl
XSLT Message: Don't know how to chunk with Apache Software FoundationSource tree node: preface. (file:///usr/share/sgml/docbook/xsl-stylesheets-1.70.1/xhtml/chunker.xsl, line 63, column 36.)
ElemMessageTerminateExpression: Don't know how to chunk with Apache Software Foundation (file:///usr/share/sgml/docbook/xsl-stylesheets-1.70.1/xhtml/chunker.xsl, line 63, column 36)

エラーになるようだ。

分割されたHTMLファイルのファイル名にid属性の値を使用する

xhtml/chunk.xslを参照するカスタムXSLを作成し、これに

<xsl:param name="use.id.as.filename" select="'1'"/>

を追加することで、

$ xsltproc [カスタムXSLの場所] booktest.xml
もしくは
$ java -jar [saxon.jarの場所] booktest.xml [カスタムXSLの場所]

とすればよいのだが、ここでは、

[xml]-+-[custom-xsl]-<xhtml-multi.xsl>
      |
      +-[doc]-[booktest]-<booktest.xml>
      |
      +-[css]-<docbook.css>
      |
      +-<xsl-stylesheets(Docbook XSLのディレクトリへのリンク)>

このようなディレクトリ構成を想定して、カスタムXSL用のディレクトcustom-xslの中に以下のファイルを作成する。
ファイル名: xhtml-multi.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:import href="../xsl-stylesheets/xhtml/chunk.xsl"/>
  <xsl:param name="use.id.as.filename" select="'1'"/>
</xsl:stylesheet>

ファイル中で参照しているDocBook XSLスタイルシート(ディストリのパッケージ)のディレクトリは、「/usr/share/sgml/docbook/xsl-stylesheets-1.70.1」のようにバージョン番号が付くディストリもあるため、その場合、カスタムXSLの中にこのディレクトリの場所を(バージョン番号入りで)書くよりも、シンボリックリンクを張る形のほうが管理上の都合は良さそう。
実際の実行の形としては、下のような形となる。

$ xsltproc ../../custom-xsl/xhtml-multi.xsl booktest.xml
もしくは
$ java -jar [saxon.jarの場所] booktest.xml ../../custom-xsl/xhtml-multi.xsl

このようにして、「use.id.as.filename」の値を1にすることで

$ xsltproc ../../custom-xsl/xhtml-multi.xsl booktest.xml
Writing preface.html for preface(preface)
Writing firstsect.html for sect1(firstsect)
Writing chap1.html for chapter(chap1)
Writing chap2.html for chapter(chap2)
Writing index.html for book
もしくは
$ java -jar [saxon.jarの場所] booktest.xml ../../custom-xsl/xhtml-multi.xsl
Writing preface.html for preface(preface)
Writing firstsect.html for sect1(firstsect)
Writing chap1.html for chapter(chap1)
Writing chap2.html for chapter(chap2)
Writing index.html for book
<?xml version="1.0" encoding="UTF-8"?>

このように、IDをファイル名にすることができる。

XHTMLCSSを指定する

カスタムXSLに

<xsl:param name="html.stylesheet" select="'[.cssファイルの場所]'"/>

を入れればよいのだが、これは、ページ分割をする場合/しない場合のいずれにも使うことができるので、
ファイル名: xhtml-common.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:param name="html.stylesheet" select="'../../css/docbook.css'"/>
</xsl:stylesheet>

上のような、XHTML変換向けの(単一/分割の)共通の設定を記述するファイルを用意して
ファイル名: xhtml-single.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>
  <xsl:import href="../xsl-stylesheets/xhtml/docbook.xsl"/>
  <xsl:import href="./xhtml-common.xsl"/>
</xsl:stylesheet>

ファイル名: xhtml-multi.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:import href="../xsl-stylesheets/xhtml/chunk.xsl"/>
  <xsl:import href="./xhtml-common.xsl"/>
  <xsl:param name="use.id.as.filename" select="'1'"/>
</xsl:stylesheet>

単一/分割のそれぞれのXSLからそれを参照する形にすると、管理しやすい。