subjectScehmeで@outputclassを検証する

もしあなたがDTDスキーマを特殊化しなければきっと@outputclassを使用するでしょう、@outputclassはいわば何でもありの属性です.

3.12.9 Other common attributes

Names a role that the element is playing. The role must be consistent with the basic semantic and expectations for the element. In particular, the @outputclass attribute can be used for styling during output processing; HTML output will typically preserve @outputclass for CSS processing.

もしある要素に何らかの特別なスタイル付けをしたければ、@outputclassはもっとも手軽に使える属性です.コンテンツが自由なので、値としてなんでも指定できてしまいます.逆に欠点は検証されないことです....とずっと思っていました.でも次の議論の中でOASIS Techinical ComittieのKristen James Eberleinさんから「@outputclassはsubjectSchemで検証できます」と指摘されました.(ちょっとスレッドが長く、該当箇所は後半の方です.)

Using Dita to produce image heavy PDF documents

これはちょっとショックでした.何故かというとsubjectSchmeはplatformなどのフィルタリング属性の値を定義するために使われるものばかりだと思っていたからです.実際DITA仕様にあるsubjectSchmeの例もplatform属性にOSに名前をバインディングするものです.

3.6.1.1 <subjectScheme>

では本当に出来るのか実際にやってみました.サンプルはxrefです.必ずDITAで出てくるのがtopicへのxrefなのですが、その出力結果として「(参照先topicの)タイトル」+「ページ番号」(title-page)、「タイトル」(title)、「ページ番号」(page)の3つが良くある出力パターンです.DITAの標準ではこれらをどうするかについては言及されていません.インプリメントする側がなんとかしなければならないのです.

これに対応するsubjectSchemeは次のようなものになります.これをメインのマップでmaprefして取り込めば良いのです.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="urn:oasis:names:tc:dita:spec:classification:rng:subjectScheme.rng" schematypens="http://relaxng.org/ns/structure/1.0"?> 
<subjectScheme>
    <subjectHead>
        <subjectHeadMeta>
            <navtitle> Constraint @outputclass for xref</navtitle>
        </subjectHeadMeta>
    </subjectHead>
    <subjectdef keys="outputclassXref">
        <subjectdef keys="title">
            <topicmeta>
                <navtitle>Output destination title only</navtitle>
            </topicmeta>
        </subjectdef>
        <subjectdef keys="title-page">
            <topicmeta>
                <navtitle>Output destination title &amp; page</navtitle>
            </topicmeta>
        </subjectdef>
        <subjectdef keys="page">
            <topicmeta>
                <navtitle>Output destination page only</navtitle>
            </topicmeta>
        </subjectdef>
    </subjectdef>
    <enumerationdef>
        <elementdef name="xref"/>
        <attributedef name="outputclass"/>
        <subjectdef keyref="outputclassXref"/>
    </enumerationdef>
</subjectScheme>

実際oXygenで@outputclassを入力しようとしたときの画像です.ちゃんとDTDスキーマで定義したがごとく属性候補が出てきます.(詳細は拡大してご覧ください.)

イメージ 1

そして@outputclassに候補でない値を入力した場合はちゃんとエラーが出てくれます.

イメージ 2

しかしDTDスキーマで検証している訳ではないので、DITA-OTで処理させると検証エラーにはなりません.そしてDITA-OTでもエラーは出ませんでした.(これをDITA-OTに望むのは無理なのでしょう.subjectSchemはあくまでもキーを定義しているのですが、そのキーはコンテンツ自身からは参照されていないのですから)

しかしとにもかくにも@outputclassはオーサリングツールではsubjectSchmeで検証できました.これはうれしい知らせです.でももう少し凝ったことをやると思わぬ結果がでてしまいました.これは次回に書きたいと思います.

※ 2016/07/11追加
しかしDTDスキーマで検証している訳ではないので、DITA-OTで処理させると検証エラーにはなりません.

これは誤りで、やり方により警告エラーが出る旨の御指摘をいただきました.警告が出るようにするためには次のようにします.

① SubjectSchmeを参照するmaprefにtype="subjectScheme"を指定します.
② これでxref/@outputclassにsubjectSchmeで指定されている以外の値を指定します.
③ oXygenでエラーが表示されますが、そのままDITA-OTに処理させます.例えばoutputclass="page-only"と指定した場合、

[DOTJ049W] The attribute value outputclass="page-only" on element "xref" does not comply with the specified subject scheme. According to the subject scheme map, the following values are valid for the outputclass attribute: page,title,title-page

とDITA-OTで警告が表示されます.ですので使えそうです.御指摘の中で参照されていたGitHubのやり取りは次のとおりです.結構前から実装されていたのですね.

Incorrect processing of subject scheme maps #1482