編集(管理者用) | 編集 | 差分 | 新規作成 | 一覧 | RSS | 表紙 | 検索 | 更新履歴

XSLTでcatalog_fileを使う

XML catalogを使うと外部からDTDを取得せずに済むらしい。 ……ということを風の噂で何となく知る。XML catalogというのは、DTDの公開識別子やシステム識別子(URI)を、ローカルのファイルパスに置き換えてくれるもののようです。

※ 取っ掛かりがXSLTだったのでこのような文書題名になってますが、XSLTに限らずlibxml2等の汎用XMLパーサにも通用する話なので、単に「XML Catalogを使う」という題にしとけばよかった、と今では思ってます。

xsltproc (libxslt)の場合

取り敢えず /etc/xml/catalog をこんな感じに。

<?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">
  <public publicId="-//W3C//DTD XHTML 1.1//EN"
    uri="xhtml11-flat.dtd"/>
  <public publicId="-//W3C//DTD XHTML 1.0 Strict//EN"
    uri="xhtml1-strict.dtd"/>
  <public publicId="-//W3C//DTD XHTML 1.0 Transitional//EN"
    uri="xhtml1-transitional.dtd"/>
  <public publicId="-//W3C//DTD XHTML 1.0 Frameset//EN"
    uri="xhtml1-frameset.dtd"/>
  <public publicId="-//W3C//DTD XHTML Basic 1.0//EN"
    uri="xhtml-basic10-f.dtd"/>
</catalog>

で、同ディレクトリ内(/etc/xml)にDTDを置きました。

あとはxsltprocがcatalogを解釈してくれます。libxml2 (xmllintコマンドなど)でもこのcatalog fileが使用されます。

Xalan-JAVAの場合

以下を参考に(Saxonについても載っています)。

やること:

catalogs=catalog
relative-catalogs=false
static-catalog=yes
catalog-class-name=org.apache.xml.resolver.Resolver
verbosity=1

catalogs=でcatalog fileを指定(上記は同じディレクトリ内の"catalog"ファイルを使う場合)。";"でつなげて複数指定可。

java org.apache.xalan.xslt.Process \
  -ENTITYRESOLVER  org.apache.xml.resolver.tools.CatalogResolver \
  -URIRESOLVER  org.apache.xml.resolver.tools.CatalogResolver \
  -in input.xml -xsl stylesheet.xsl -out output.xml

CatalogManager.propertiesでverbosity=4にすると、DTDの解決状況が出力されます。うまく行かない時の確認などに。

はまった点

WindowsのJ2RE(1.4.2_03)を使って試していたのですが、これには元々Xalan(2.4.1)が入っているらしく、ふつうにCLASSPATHにxalan.jarを設定するだけでは置き換わらない様です。このXalan(2.4.1)だと-ENTITYRESOLVERオプションをきちんと解釈してくれない……と思っていたのですが、実はただ単にresolver-1.0.jarが読み込まれていないのが原因だったようでした。

以下の記事を参考にして、lib/endorsed ディレクトリ内にresolver-1.0.jarを置くとうまくいきました。

lib/endorsed に新しいxalan.jarを置けば元からあるXalanも置き換えることができるのですが、Xalan 2.6.0を入れると文字コードの変換が上手く行かないようです(&hearts;をshift_jisで出力する時に&#9829;に変換せず?にしたりとか)。

他参考リンク