ちょっと進んで(?)次のように複数のパッケージを試してみます.
[test-pkg-xslt3.xsl]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
package-version="1.0"
name="urn:test:pkg:xslt3"
exclude-result-prefixes="xs ahf"
version="3.0"
default-mode="normal">
<xsl:mode name="normal" visibility="public"/>
<xsl:mode/>
<xsl:template match="*[contains(@class,' topic/ph ')]" name="tplPh">
<fo:inline>
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
package-version="1.0"
name="urn:test:pkg:xslt3"
exclude-result-prefixes="xs ahf"
version="3.0"
default-mode="normal">
<xsl:mode name="normal" visibility="public"/>
<xsl:mode/>
<xsl:template match="*[contains(@class,' topic/ph ')]" name="tplPh">
<fo:inline>
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:template match="*[contains(@class,' hi-d/b ')]" priority="2" name="tplB">
<fo:inline font-weight="bold">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:function name="ahf:setRed" as="attribute()*" visibility="public">
<xsl:attribute name="color" select="'red'"/>
</xsl:function>
</xsl:package>
<fo:inline font-weight="bold">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
<xsl:function name="ahf:setRed" as="attribute()*" visibility="public">
<xsl:attribute name="color" select="'red'"/>
</xsl:function>
</xsl:package>
[test-pkg2-xslt3.xsl]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
package-version="1.0"
name="urn:test:pkg2:xslt3"
exclude-result-prefixes="xs ahf"
version="3.0"
default-mode="normal">
<xsl:mode name="normal" visibility="public"/>
<xsl:mode/>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
package-version="1.0"
name="urn:test:pkg2:xslt3"
exclude-result-prefixes="xs ahf"
version="3.0"
default-mode="normal">
<xsl:mode name="normal" visibility="public"/>
<xsl:mode/>
<xsl:template match="*[contains(@class,' hi-d/i ')]" priority="2" name="tplI">
<fo:inline font-style="italic">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
</xsl:package>
<fo:inline font-style="italic">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
</xsl:package>
[test-pkg-main2-xslt3.xsl]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
exclude-result-prefixes="xs math ahf"
name="urn:test:pkg:main:xslt3"
default-mode="normal"
version="3.0"
>
<xsl:use-package name="urn:test:pkg:xslt3"/>
<xsl:use-package name="urn:test:pkg2:xslt3"/>
<xsl:mode name="normal" visibility="public"/>
<xsl:template match="/*">
<fo:block>
<xsl:copy-of select="ahf:setRed()"/>
<xsl:apply-templates mode="normal"/>
</fo:block>
</xsl:template>
</xsl:package>
<xsl:package xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:ahf="http://www.antennahouse.com/Names/XSLT/Document"
exclude-result-prefixes="xs math ahf"
name="urn:test:pkg:main:xslt3"
default-mode="normal"
version="3.0"
>
<xsl:use-package name="urn:test:pkg:xslt3"/>
<xsl:use-package name="urn:test:pkg2:xslt3"/>
<xsl:mode name="normal" visibility="public"/>
<xsl:template match="/*">
<fo:block>
<xsl:copy-of select="ahf:setRed()"/>
<xsl:apply-templates mode="normal"/>
</fo:block>
</xsl:template>
</xsl:package>
大きな意味はありません.、単純に従来機能単位にモジュールで記述していたものをxsl:packageにしたらどうなるか?を試しただけです.これをSaxon 9.8の最新版で実行すると、次のようにあえなくエラーではじかれます.
C:\Users\toshi\OneDrive\Documents\test\xslt\20170718-package>java -jar D:\My_Documents\Java\SaxonEE9-8-0-3J\saxon9ee.jar
-s:input.xml -o:output-saxon.xml -xsl:test-pkg-main2-xslt3.xsl -config:saxon-config.xml -t
Saxon-EE 9.8.0.3J from Saxonica
Java version 1.8.0_60
Using license serial number V005977
Static error at xsl:mode on line 16 column 50 of test-pkg-main2-xslt3.xsl:
XTSE3050: Mode normal conflicts with a public mode declared in package urn:test:pkg:xslt3
Errors were reported during stylesheet compilation
-s:input.xml -o:output-saxon.xml -xsl:test-pkg-main2-xslt3.xsl -config:saxon-config.xml -t
Saxon-EE 9.8.0.3J from Saxonica
Java version 1.8.0_60
Using license serial number V005977
Static error at xsl:mode on line 16 column 50 of test-pkg-main2-xslt3.xsl:
XTSE3050: Mode normal conflicts with a public mode declared in package urn:test:pkg:xslt3
Errors were reported during stylesheet compilation
これはnormalと名付けられたモードが、競合するというメッセージです.
あれ?なんでこんな解釈になってしまうか?とXSLT 3.0の仕様を追うと次のようになっています.
1. まずパッケージで定義されるモードはコンポーネントという概念の一つに考えられます.
"The components which can be declared in one package and referenced in another are: functions, named templates, attribute sets, modes, and global variables and parameters."
2.2つのコンポーネントは同じ識別子を持つとき同名(homonymous)とされます.
"[Definition: Two components are said to be homonymous if they have the same symbolic identifier.]"
3.xsl:packageの中で使っているxsl:packageとコンポーネントが同名になるのは静的エラーです.
"[ERR XTSE3050] It is a static error if the xsl:use-package elements in a package manifest cause two or more homonymous components to be accepted with a visibility other than hidden."
まあ関数名なんかが同じ名前(ネームスペースも含め)なら確かに競合と言われてもおかしくないのですがmodeが同じ名前ではダメということは、xsl:apply-templatesやxsl:templateで指定するmode属性は、xsl:packageをまたがって共通にはできないということを意味しています.
この影響は非常に大きいと思います.私たちはスタイルシートをつくるときxsl:apply-templatesは
* 実は私はこの子ノードを処理する呼び出しの先のxsl:templateがどのようにインプリメントされているかは知りません.
* しかし、完成されたスタイルシートならばどこかのスタイルシートモジュールで、適切なxsl:templateが定義されているのでしょう.
* もし定義されていなければビルトインテンプレートが起動されることに異存はありません.
* しかし、完成されたスタイルシートならばどこかのスタイルシートモジュールで、適切なxsl:templateが定義されているのでしょう.
* もし定義されていなければビルトインテンプレートが起動されることに異存はありません.
この問題でxsl-listに疑問をポストしてみました.
[xsl] Mode in XSLT 3.0
http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/201707/msg00062.html
http://www.biglist.com/lists/lists.mulberrytech.com/xsl-list/archives/201707/msg00062.html
XSLT 3.0のエディタのMichael Kay博士の基本的な考え方は次のようなものです.
The thinking is that if package A uses packages B and C, then B and C were
developed and tested independently and have no knowledge of each other or
dependence on each other. When a template rule in B calls apply-templates,
it's not expecting a template rule in C to be invoked, because it was written
with no knowledge of C.
developed and tested independently and have no knowledge of each other or
dependence on each other. When a template rule in B calls apply-templates,
it's not expecting a template rule in C to be invoked, because it was written
with no knowledge of C.
「パッケージAがパッケージB,Cを使用していて、これらは互いに内部を知ることはなく独立して開発されている場合、Bの中でのxsl:apply-templatesはCのxsl:templateを呼び出すことは期待されない.そもそもBはCの何たるかを知ることなく開発されているからである.」
つまりxsl:packageは非常に独立性の高いことが想定されていて、その中でのxsl:apply-templatesは「中に閉じて処理」されます.
* 段落(p)はテキストだkでなく、表(table)やol,ul(番号付きリスト、番号なしリスト)を内部にコンテンツとして持つことができます.
* ol,ul/liは段落(p)を子要素として持つことができます.
* 表のセル(entry)は、段落(p)を子要素に持つことができます.
* ol,ul/liは段落(p)を子要素として持つことができます.
* 表のセル(entry)は、段落(p)を子要素に持つことができます.
従って、モジュール分割をして、段落を処理するスタイルシートモジュール、リスト(ol.ul)を処理するスタイルシートモジュール、表(table)を処理するスタイルシートモジュールを作ってもそれらは決して独立ではなく、xsl:apply-templatesで互いに「呼び出し合う」結果となります.
ですので、このような構造に根差したテンプレートをxsl:packageで記述しようとすれば、すべての互いに呼び出し合う可能性のあるxsl:templateを一つのxsl:packageに入れなければならないという結果になってしまいます.これは到底受け入れることはできません.