8年目のエラー

毎週明日は休みの金曜日というところになって、退社時間が迫ってくるとどういうわけか決まってお客さんから障害報告が来ます.今週はDocBook→XSL-FOのスタイルシートで見たことのないエラーメッセージというものでした.エラーメッセージは
 
「Recoverable error Non-text output nodes are ignored when writing an attribute, comment, or PI」
 
というものです.Saxon6.5のものですが、お客様のシステムはもう足かけ8年目の運用なのですがついぞこのエラーは見たことがありません.つまり8年ぶりのエラーです.またSaxonのエラーメッセージはMSXMLなんかにくらべてとても親切なのですが、このメッセージは行番号が表示されていません.「コマンドラインで"-t"オプションをつければわかるかも!」と思ってやってみましたがやはり結果は同じです.WEBを探してみると、Saxon HelpにMichael Kayの解説が載っていました.
 
 
どうもキーポイントは"-t"ではなく"-T"オプションのようです.やってみるとXSLTの命令とデータをトレースするので山ほど標準エラー出力にログが出ますが、エラーメッセージの直前のログデータでどのデータを処理していたときかがわかります.該当のデータを探し当てると次のようなものでした.
 
<chapter id="id00053562">
    <title>Appendices</title>
    <section id="id00053563">
        <title><xref linkend="id00053563" xrefstyle="plain-page"/></title>
        ....
    </section>
    ...
</chapter>
 
なんとsectionのtitle内にxrefがあり、そのリンク先がsection(この場合、section/titleを指す規約)という循環参照になっていました.何故このようなことがおきるのかというと、DocBookはset単位で編集すると大変なので、およそsection単位で区切って分散オーサリングします.このときset/chspter/sectionの骨組みだけのデータをxrefの参照用につくり、参照は分散オーサリングしたsectionから、この骨組みデータに向かって行います.そして最後に、骨組みデータに個々のsectionをバインドして一個のDocBookのインスタンスを作り出します.
 
骨組みデータには、set/chspter/sectionと各要素のid、仮のtitleをつけます.どうもオーサリング担当者はsectionのタイトルのオーサリングを簡略化するために、骨組みデータの自身のsectionの仮のtitleを参照しようとしてこんなデータを作ってしまったようです.
 
それでもDITA→XSL-FOのスタイルシートはよくこんなデータでループしないで動いてくれました.ちなみに「Recoverable error Non-text output nodes are ignored when writing an attribute, comment, or PI」というエラーは、属性、コメント、処理命令を生成するときに、その中でテキスト以外の、要素や属性を生成すると無視されるというものです.
 
このエラー、本当にSaxonを使い始めてからは初めてお目にかかったものでした.システムも何年も運用していると時にはとんでもないエラーが出るものです.