XSLT3.0への道(7) その他の要素

現在まで紹介したXSLT3.0の要素ですがこれらはすでにSaxon9.3に実装されているものです.Saxon9.3の実装状況は次のURLで確認できます.
ここではSaxon PEでは使えなかったり、またまだSaxon 9.3では実装されていない要素などを一覧としてあげておきます.使えないので仕様書を見るしかありません.この手の仕様は、なかなか仕様書だけ読んでいてもチンプンカンプンで実際に使ってみないとわからないものです.その点か書き手の能力に依存します.あらかじめご容赦ください.
 
■ xsl:context-item
xsl:modeでinitial="yes"を指定したときに、そのモードがXSLTプロセッサが起動したときの初期に採用するモードになります.このxsl:modeの子要素としてxsl:context-itemを記述し最初のコンテキストアイテムを指定できます.例えばドラフトでは
<xsl:mode name="invoice" initial="yes" on-no-match="copy">
  <xsl:context-item as="schema-element(invoice)">
</xsl:mode>
と書いて、"invoce"と名づけられたモードでXSLTプロセッサが動き出すことを指定し、その時の最初のコンテキストアイテムが、スキーマでバリデーションされたinvoceという要素であることを指定しています.たぶんinvoice要素から処理が開始されるでしょう.
 
■ xsl:stream
href属性でURIを指定し、それをソースドキュメントとして読み込みます.処理はxsl:streamの子要素でストリームモードで処理されます.
<xsl:stream href="book.xml">
  <xsl:for-each select="book/chapter">
    <xsl:result-document href="chapter{position()}.xml">
      <xsl:copy-of select="."/>
    </xsl:result-document>
  </xsl:for-each>
</xsl:stream>
 
のような例が載っています.ストリームモードを使わなければ次のように書けるでしょう.
 
<xsl:variable name="src" select="doc('book.xml')">
<xsl:for-each select="$src/book/chapter">
  <xsl:result-document href="chapter{position()}.xml">
    <xsl:copy-of select="."/>
  </xsl:result-document>
</xsl:for-each>
 
逆を言えば、xsl:streamはこのような例をストリームモードで高速に簡単に処理させる機構ですね.
 
■ xsl:merge
これは大変な機能です.xsl:mergeは、あらかじめソートされた複数の入力から、マージキーに従ってマージされた結果を出力するというものです.子要素の xsl:merge-source でソースドキュメントを指定し、xsl:merge-actionで処理を記述します.ドラフトにはこの部分は相当なスペースを割いて仕様を記述しています.実際の例はドラフトを見ていただいた方が良いでしょう.最初に載っている例がこれです.
 
 
なかなか読解するのも大変です.しかし、考えてみれば事務処理分野のCOBOLでは、ソート/マージしてなんていうのは日常茶飯事の仕事です.昔どれくらいこの手のCOBOLのプログラムとお付き合いしたか思い出しきれません.XMLの分野ではこういう処理は今までどうしていたのかと考えると不思議です.たぶん発展途上のXMLに対するデータ処理分野からの強い要望があるのでしょう.
 
■ xsl:fork
xsl:forkは少し奇妙な要素です.その子要素から生成されるsequence-consutructorに含まれる命令が各々独立しているので、ストリームモードの処理で独立して扱うようにプロセッサにsuggestionするというものです.こんな例が載っています.
 
<xsl:mode on-no-match="copy" streamable="yes"/>
<xsl:template match="note"/>
<xsl:template match="/*">
  <xsl:fork>
    <xsl:apply-templates/>
    <footnote>
      <p>Removed <xsl:value-of select="count(.//note)"/>
                 note elements.</p>
    </footnote>
  </xsl:fork>
</xsl:template>
              
確かにxsl:apply-templatesとfootnoteは完全に独立しています.ストリームモードではone pathで入力データを処理するので、このような情報を与えればプロセッサは前者と後者を更にパラレルに処理するように最適化ができると考えられます.最適化しなくても良いなら、xsl:forkを指定しなくても結果は変わらないはずです.
 
■ xsl:copy
select属性が追加され、コピーの対象を指定できるようになっています.selectのデフォルトは"."です.(xsl:copyはSaxon 9.3では実装されています.)
 
さてXSLTのドラフト仕様というのは、相手が英文となるとなかなか読むのもおっくうなものです.しかし実際読んでみると今後がどうなってゆくのかの一端を知ることができます.やっぱりテクノロジーの発達にはロマンがありますね.