東日本大震災で被災された方に心よりお見舞いを申し上げます.
今回はxsl:modeを紹介します.私は最初ちょっと眺めただけでxsl:modeはストリーミングをサポートするために付け加わったものと思っていましたがそうではないようです.今までmode属性は、例えば、
<xsl:template match="*" mode="COPY">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-template mode="COPY"/>
</xsl:copy>
</xsl:template>
のように結構適当に使ってきました.このmode属性に指定した名前を定義する命令はなかったわけです.xsl:modeは次のようなフォーマットで、この「モード」の様々な機能設定を行えます.
<xsl:mode
name? = qname
streamable? = "yes" | "no"
initial? = "yes" | "no"
on-no-match? = "stringify" | "discard" | "copy" | "fail"
on-multiple-match? = "use-last" | "fail"
warning-on-no-match? = "yes" | "no"
warning-on-multiple-match? = "yes" | "no" >
<!-- Content: (xsl:context-item?) -->
</xsl:mode>
name? = qname
streamable? = "yes" | "no"
initial? = "yes" | "no"
on-no-match? = "stringify" | "discard" | "copy" | "fail"
on-multiple-match? = "use-last" | "fail"
warning-on-no-match? = "yes" | "no"
warning-on-multiple-match? = "yes" | "no" >
<!-- Content: (xsl:context-item?) -->
</xsl:mode>
streamableはストリーミングを規定します.残念ながらSaxon PEでは使えないので、残りを解説します.
■ name
nameはモードの名前です.例えばname="COPY"とすれば先ほどのmode="COPY"の動作を規定することができます.もしnameが指定されなければ、「名前なしモード(unnamed mode)」で、xsl:templateやxsl:apply-templatesでmode属性を使用しない通常のモードの動作を規定します.
nameはモードの名前です.例えばname="COPY"とすれば先ほどのmode="COPY"の動作を規定することができます.もしnameが指定されなければ、「名前なしモード(unnamed mode)」で、xsl:templateやxsl:apply-templatesでmode属性を使用しない通常のモードの動作を規定します.
■ initial
もしスタイルシートが、名前なしモードのxsl:templateやxsl:apply-templatesを1つも持っていないとき、initial="yes"のモードがデフォルトで動作します.(あまりそういうスタイルシートの作り方はしないと思いますが...)
もしスタイルシートが、名前なしモードのxsl:templateやxsl:apply-templatesを1つも持っていないとき、initial="yes"のモードがデフォルトで動作します.(あまりそういうスタイルシートの作り方はしないと思いますが...)
■ on-no-match
マッチするxsl:templateが無かったときのビルトインテンプレートの処理ルールを規定します.on-no-match="stringfy"はXSLT1.0と同じで、要素ではselect属性なしのxsl:apply-templateの呼び出しとなり、テキストノードや属性ノードはそのテキストの出力となります.on-no-match="discard"は、結果ツリーに何も残しません.on-no-match="copy"は、入力ツリーが結果ツリーにそのままコピーされます.on-no-match="fail"は、このような場合エラー扱いとなります.
マッチするxsl:templateが無かったときのビルトインテンプレートの処理ルールを規定します.on-no-match="stringfy"はXSLT1.0と同じで、要素ではselect属性なしのxsl:apply-templateの呼び出しとなり、テキストノードや属性ノードはそのテキストの出力となります.on-no-match="discard"は、結果ツリーに何も残しません.on-no-match="copy"は、入力ツリーが結果ツリーにそのままコピーされます.on-no-match="fail"は、このような場合エラー扱いとなります.
■ on-multiple-match
このエラーはDITAのスタイルシートを作るときによくお目にかかります.ノードが同じpriorityで複数のtemplateのmatch条件に合致してしまった場合の処理を規定します.on-multiple-match="use-last"は後に定義されたテンプレートを採用します.on-multiple-match="fail"は回復不可能なエラーとなります.
このエラーはDITAのスタイルシートを作るときによくお目にかかります.ノードが同じpriorityで複数のtemplateのmatch条件に合致してしまった場合の処理を規定します.on-multiple-match="use-last"は後に定義されたテンプレートを採用します.on-multiple-match="fail"は回復不可能なエラーとなります.
■ warning-on-no-match
xsl:apply-templatesがどのxsl:templateにもマッチしないとき、エラーを出すか否かを"yes","no"で指定します.
xsl:apply-templatesがどのxsl:templateにもマッチしないとき、エラーを出すか否かを"yes","no"で指定します.
■ warning-on-multiple-match
ノードが同じpriorityで複数のtemplateのmatch条件に合致してしまった場合、警告を出すか否かを"yes","no"で指定します.
ノードが同じpriorityで複数のtemplateのmatch条件に合致してしまった場合、警告を出すか否かを"yes","no"で指定します.
名前なしモードでxsl:modeを使ってみた例を示します.
[入力ファイル]
<?xml version="1.0" encoding="UTF-8" ?>
<data>
<product type="pencil" maker="三菱" price="100" count="5"/>
<?comment Below data element is commentted. ?>
<!--product type="pencil" maker="コーリン" price="90" count="10"/-->
</data>
<?xml version="1.0" encoding="UTF-8" ?>
<data>
<product type="pencil" maker="三菱" price="100" count="5"/>
<?comment Below data element is commentted. ?>
<!--product type="pencil" maker="コーリン" price="90" count="10"/-->
</data>
[スタイルシート]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
>
<xsl:output indent="yes"/>
<xsl:mode streamable="no"
on-no-match="copy"
on-multiple-match="use-last"
warning-on-no-match="yes"
warning-on-multiple-match="yes">
</xsl:mode>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[not(@extra)]">
<xsl:message select="'Former template is adopted!'"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(@dummy)]">
<xsl:message select="'Latter template is adopted!'"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
>
<xsl:output indent="yes"/>
<xsl:mode streamable="no"
on-no-match="copy"
on-multiple-match="use-last"
warning-on-no-match="yes"
warning-on-multiple-match="yes">
</xsl:mode>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[not(@extra)]">
<xsl:message select="'Former template is adopted!'"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(@dummy)]">
<xsl:message select="'Latter template is adopted!'"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
[ログ]
Recoverable error
XTRE0540: Ambiguous rule match for /data
Matches both "*[not(@dummy)]" on line 27 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
and "*[not(@extra)]" on line 19 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
Latter template is adopted!
Warning: No user-defined template rule found for node /data/text()[1]
Recoverable error
XTRE0540: Ambiguous rule match for /data/product[1]
Matches both "*[not(@dummy)]" on line 27 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
and "*[not(@extra)]" on line 19 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
Latter template is adopted!
Warning: No user-defined template rule found for node /data/text()[2]
Warning: No user-defined template rule found for node /data/processing-instructi
on()[1]
Warning: No user-defined template rule found for node /data/text()[3]
Warning: No user-defined template rule found for node /data/comment()[1]
Warning: No user-defined template rule found for node /data/text()[4]
Recoverable error
XTRE0540: Ambiguous rule match for /data
Matches both "*[not(@dummy)]" on line 27 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
and "*[not(@extra)]" on line 19 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
Latter template is adopted!
Warning: No user-defined template rule found for node /data/text()[1]
Recoverable error
XTRE0540: Ambiguous rule match for /data/product[1]
Matches both "*[not(@dummy)]" on line 27 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
and "*[not(@extra)]" on line 19 of
file:/C:/Documents%20and%20Settings/toshi/style.xsl
Latter template is adopted!
Warning: No user-defined template rule found for node /data/text()[2]
Warning: No user-defined template rule found for node /data/processing-instructi
on()[1]
Warning: No user-defined template rule found for node /data/text()[3]
Warning: No user-defined template rule found for node /data/comment()[1]
Warning: No user-defined template rule found for node /data/text()[4]