今回はURI関係の関数です.XSLT1.0ではこの分野の関数はありませんでした.様々な関数が追加されていますがどのようなものがあるでしょうか?
例えば、
パラメータなしのbase-uri() は base-uri(.) と同じで、一例として"file:/C:/Documents%20and%20Settings/tmakita/My%20Documents/xslt-test/uri/data/input.xml"を返します.
またbase-uri(document(''))としてやれば、一例として"file:/C:/Documents%20and%20Settings/tmakita/My%20Documents/xslt-test/uri/xsl/test.xsl"を返します.
XSLT1.0では、入力XMLファイルはXSLTプロセッサに対するパラメータとしてパスを指定してやるのであって、スタイルシートの中ではそのパスを知る由もありませんでした.base-uei()を使用すれば、入力XMLファイルやスタイルシートのURIを取得できます.
例えば、base-uri()の例で、resolve-uri('data2.xml',base-uri())は、"file:/C:/Documents%20and%20Settings/tmakita/My%20Documents/xslt-test/uri/data/data2.xml"
を返します.
例えば、input.xmlを入力するスタイルシートで、documet-uri(/)は、"file:/C:/Documents%20and%20Settings/toshi/My%20Documents/xslt-test/uri/data/input.xml"を返します.
例えば、static-base-uri()は、"file:/C:/Documents%20and%20Settings/tmakita/My%20Documents/xslt-test/uri/xsl/test.xsl"を返します.
■ doc(), doc-available()
doc()関数は、xs:stringでURIを与えてXMLファイルをロードし、そのdocument-node()を返します.doc-available()は、同様ですがファイルの存在をチェックして結果をxs:booleanで返します.
doc()関数は、xs:stringでURIを与えてXMLファイルをロードし、そのdocument-node()を返します.doc-available()は、同様ですがファイルの存在をチェックして結果をxs:booleanで返します.
外部のXMLファイルへのアクセスは、XSLT1.0ではdocument()関数だけでした.doc()はXSLT2.0でもあるdocument()関数のシンプル版です.またXSLT1.0ではファイルの有無の確認するような関数はありませんでした.doc-available()を使って、安全にアクセスできるようになりました.
#base-uri(), documet-uri(), static-base-uri()とresolve-uri()の組み合わせでdoc()関数を使えば、入力XML相対または、スタイルシート相対から絶対URIを生成できるので様々な位置のXMLファイルにアクセスできます.
■ unparsed-text(), unparsed-text-available()
unparsed-text()は、xs:string?でURIを、xs:stringでencodingを与えてテキストファイルの内容をxs:stringで返します.unparsed-text-available()も同じパラメータで、テキストファイルがアクセスできるか否かを返します.
unparsed-text()は、xs:string?でURIを、xs:stringでencodingを与えてテキストファイルの内容をxs:stringで返します.unparsed-text-available()も同じパラメータで、テキストファイルがアクセスできるか否かを返します.
外部のファイルへのアクセスはXSLT1.0ではXMLファイルだけでした.この2つの関数により、スタイルシートからテキストファイルにアクセスできるようになりました.これはXSLTの可能性を非常に高めるものです.うまい使い方をすればCSVファイルからXMLを作るようなこともできるでしょう.これについては、改めて紹介したいと思います.
例えば、encode-for-uri('ウィキペディア')は、"%E3%82%A6%E3%82%A3%E3%82%AD%E3%83%9A%E3%83%87%E3%82%A3%E3%82%A2" を返します.
■ collection()
collection()は、xs:string?のURIをパラメータとして、node()*、一般的にはドキュメントノードのシーケンスを返します.URIが複数のドキュメントを格納する機構についてはインプリメンテーション依存のようです.Altovaの場合はカタログファイルと呼ばれるもの、もしくはcollection("*.xml")というような記法を許します.Saxonの場合はカタログファイルもしくは、ディレクトリを指したURIの指定が可能です.後者の場合、ディレクトリの下のすべてのXMLファイルが返されます.
collection()は、xs:string?のURIをパラメータとして、node()*、一般的にはドキュメントノードのシーケンスを返します.URIが複数のドキュメントを格納する機構についてはインプリメンテーション依存のようです.Altovaの場合はカタログファイルと呼ばれるもの、もしくはcollection("*.xml")というような記法を許します.Saxonの場合はカタログファイルもしくは、ディレクトリを指したURIの指定が可能です.後者の場合、ディレクトリの下のすべてのXMLファイルが返されます.
このカタログファイルはNorman Walshさんが開発した例のJavaのカタログファイルとは異なります.
例えば、catalog.xmlをデータフォルダに置き、内容を
<collection>
<doc href="input_1.xml"/>
<doc href="input_2.xml"/>
<doc href="input_3.xml"/>
</collection>
<doc href="input_1.xml"/>
<doc href="input_2.xml"/>
<doc href="input_3.xml"/>
</collection>
とします.スタイルシートで、要素が<data/>だけの入力ファイルを読み込み、
<xsl:template match="data">
<xsl:variable name="collection" select="collection(resolve-uri('catalog.xml',base-uri()))" as="node()*"/>
<xsl:copy>
<xsl:copy-of select="$collection"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="collection" select="collection(resolve-uri('catalog.xml',base-uri()))" as="node()*"/>
<xsl:copy>
<xsl:copy-of select="$collection"/>
</xsl:copy>
</xsl:template>
URI関連ではあまりに関数が追加になり整理が大変ですね.