XSLT 2.0で便利になった機能(18) URI関係の関数

今回はURI関係の関数です.XSLT1.0ではこの分野の関数はありませんでした.様々な関数が追加されていますがどのようなものがあるでしょうか?
 
■ base-uri()
base-uri()はnode()?をパラメータとして、そのbase-URIを返します.一般的にはnode()が入力XMLファイルのものであるときは、そのURIを返します.
 
例えば、
パラメータなしの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を取得できます.
 
■ resolve-uri()
resolve-uri()は、xs:strng?のURI参照、xs:stringのベースURIを指定して、絶対URIを返します.
 
例えば、base-uri()の例で、resolve-uri('data2.xml',base-uri())は、"file:/C:/Documents%20and%20Settings/tmakita/My%20Documents/xslt-test/uri/data/data2.xml"
を返します.
 
■ document-uri()
document-uri()は、node()?でdocument-node()を指定し、そのURIを返します.
 
例えば、input.xmlを入力するスタイルシートで、documet-uri(/)は、"file:/C:/Documents%20and%20Settings/toshi/My%20Documents/xslt-test/uri/data/input.xml"を返します.
 
■ static-base-uri()
static-base-uri()は、パラメータなしで用いられ、一般的にはスタイルシートURIを返します.
 
例えば、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で返します.
 
外部の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()も同じパラメータで、テキストファイルがアクセスできるか否かを返します.
 
外部のファイルへのアクセスはXSLT1.0ではXMLファイルだけでした.この2つの関数により、スタイルシートからテキストファイルにアクセスできるようになりました.これはXSLTの可能性を非常に高めるものです.うまい使い方をすればCSVファイルからXMLを作るようなこともできるでしょう.これについては、改めて紹介したいと思います.
■ encode-for-uri()
encode-for-uri()は、xs:stringのパラメータをRFC3986に従って特殊文字を%でエスケープした文字列を返します.
 
例えば、encode-for-uri('ウィキペディア')は、"%E3%82%A6%E3%82%A3%E3%82%AD%E3%83%9A%E3%83%87%E3%82%A3%E3%82%A2" を返します.
 
■ escape-html-uri()
escape-html-uri() は、xs:stringのパラメータをHTML4.0の仕様に従って非アスキー文字をエスケープして結果を返します.
 
例えば、escape-html-uri('http://新宿駅.jp/';)は、"http://%E6%96%B0%E5%AE%BF%E9%A7%85.jp/"を返します.
 
■ iri-to-uri()
iri-to-uri()は、RFC 3986, RFC 3987に基づいてIRIの特殊文字を%エンコーディングしてURIとして返します.
 
例えば、iri-to-uri('My Document.xml') は、"My%20Document.xml" を返します.
 
■ collection()
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>
 
とします.スタイルシートで、要素が<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>
 
とすれば、出力の<data>要素の下に、input_1.xml、input_2,xml、input_3.xmlの内容をコピーすることができます.
 
URI関連ではあまりに関数が追加になり整理が大変ですね.