For Gauche 0.9.5


Next: , Previous: , Up: ライブラリモジュール - ユーティリティ   [Contents][Index]

12.45 sxml.sxpath - SXMLクエリ言語

Module: sxml.sxpath

SXPathは、XML Information set (Infoset)のインスタンスのS式フォームである SXMLのためのクエリ言語です。

これは最初にOleg Kiselyovによって書かれ、Dmitry LizorkinとKirill Lisovsky によって改良されました。 このモジュールにはまた、Dmitry LizorkinとKirill LisovskyによりSXPathのために 書かれたたくさんの手続きが盛り込まれています。

現在のバージョンは、sxpathlib.scm v3.915、sxpath.scm v1.1、sxpath-ext.scm v1.911を ベースにしています。

このマニュアルは、そのほとんどがオリジナルのソースファイルのコメントより 導出されています。

このモジュールは3つのレイヤから構成されます。

  1. SXMLツリーへのアクセスやその変換の手段を提供する基本的なコンバータや アプリケータ(適用子)。
  2. 省略形のSXPathを取り、与えられたノードセットから指定されたパスを満足する ノードセットを選択するScheme関数を返す、高レベルなクエリ言語コンパイラ。
  3. W3CのXPathコア関数ライブラリのSXML版を実装する拡張ライブラリ。

Next: , Previous: , Up: SXMLクエリ言語   [Contents][Index]

12.45.1 SXPathの基本的なコンバータとアプリケータ

コンバータは、以下を満たす関数です。

  type Converter = Node|Nodeset -> Nodeset

コンバータは、述語としての役割を担うこともあります。 その場合、コンバータが、ノードやノードセットに適用され、空ではないノードセットを 返す場合、述語としてのコンバータは満足したものとみなされます。 このファイルを通して、nilノードセットは失敗を表す#fと等価です。

Function: nodeset? x

与えられたオブジェクトがノードセットならば、#tを返します。

Function: as-nodeset x

xがノードセットならば、それをそのまま返し、そうでなければそれを リストでラップして返します。

Function: sxml:element? obj

objがSXMLの要素であれば#tを返し、そうでなければ#fを 返す述語です。

Function: ntype-names?? crit

関数ntype-names??は、判定基準として受け付け可能なノード名のリストを取り、 関数を返します。この関数は、ノードに適用された際、そのノード名が判定基準リストに 含まれていれば#tを、含まれていなければ#fを返す関数です。

 ntype-names?? :: ListOfNames -> Node -> Boolean
Function: ntype?? crit

関数ntype??は、型に関する判定基準を取り、関数を返します。 この関数は、ノードに適用された際、そのノードがそのテストを満足するかを 返します。

  ntype?? :: Crit -> Node -> Boolean

判定基準critは、以下のシンボルのうちの1つです。

id

そのノードが正しい名前(id)を持っているかをテストします。

@

そのノードがattributes-listであるかをテストします。

*

そのノードがElementであるかをテストします。

*text*

そのノードがテキストノードであるかをテストします。

*data*

そのノードがデータノード(テキスト、数値、真偽値などで、ペアではない)であるか をテストします。

*PI*

そのノードがPIノードであるかをテストします。

*COMMENT*

そのノードがCOMMENTノードであるかをテストします。

*ENTITY*

そのノードがENTITYノードであるかをテストします。

*any*

どんなタイプのノードに対しても#tを返します。

Function: ntype-namespace-id?? ns-id

この関数は、名前空間IDを取り、述語Node -> Booleanを 返します。この述語はまさにその名前空間IDを持つノードに対しては #tを返します。ns-idは文字列です。 (ntype-namespace-id?? #f)は、完全修飾されていない名前を 持つノードに対して#tを返します。

Function: sxml:invert pred

この関数は、述語を取り、それを反対にして返します。 与えられた述語が#fや’()を返す場合、反対にされたものは 与えられたノード(#t)を返します。

Function: node-eq? other
Function: node-equal? other

等価な述語としてのコンパータにカリー化します。すなわち、

  ((node-eq? a) b)    ≡ (eq? a b)
  ((node-equal? a) b) ≡ (equal? a b)
Function: node-pos n
 node-pos:: N -> Nodeset -> Nodeset, or
 node-pos:: N -> Converter

ノードセットのN番目の要素を選択し、1つの要素を持つノードセットを返します。 N番目の要素が存在しなければ、空のノードセットを返します。 ((node-pos 1) Nodeset)は、ノードセットの先頭ノードがあればそれを選択します。 ((node-pos 2) Nodeset)は、2番目のノードがあればそれを選択します。 Nは負の数でも構いません。その場合、ノードはリストの末尾から数えられます。 ((node-pos -1) Nodeset)は、空ではないノードセットの最後のノードを選択します。 ((node-pos -2) Nodeset)は、最後から2番目のノードがあればそれを選択します。

Function: sxml:filter pred?
 filter:: Converter -> Converter

フィルタリングを行う、フィルタアプリケータです。 引数のコンバータは、#fあるいはnilとなることが失敗を意味する述語と みなされます。

Function: take-until pred?
 take-until:: Converter -> Converter, or
 take-until:: Pred -> Node|Nodeset -> Nodeset

述語としてのコンバータとノードセットが与えられると、 ノードセットの各要素に述語を適用し、 述語が#fあるいはnil以外を返すと、 (その述語が失敗した)その時点までに処理された要素を返します。 take-untilは、上のフィルタのバリエーションの1つです。 take-untilは、その述語を満足する最初の要素(それ自体は含まない)まで、 順序付けられた入力のセットの要素をパスします。 ((take-until (not pred)) nset)により返されるノードセットは、 ((filter pred) nset)により返されるノードセットのサブセット – 具体的には接頭辞 –になります。

Function: take-after pred?
take-after:: Converter -> Converter, or
take-after:: Pred -> Node|Nodeset -> Nodeset

述語としてのコンバータとノードセットを与えると、 述語をノードセットの各要素に適用し、 述語が#fかnil以外を返すと、 まだ述語が適用されていない要素を返します。 つまり、述語を満足する最初の要素の後に続く要素を返します。 take-aftertake-untilを一緒に使うと、 入力のノードセットを3つのパート: 述語を満足する最初の要素、その要素の前の部分、その要素の後の部分に 分けます。

Function: map-union proc lst

procをlstの各要素に適用し、結果のリストを返します。 procがノードセットを返す場合、それを結果につなぎ合わせます。

別の観点から見ると、map-unionはConverter->Converter関数で、 結合を行いたいコンテキストでの引数としてのコンバータに 位置します。

Function: node-reverse node-or-nodeset
node-reverse :: Converter, or
node-reverse:: Node|Nodeset -> Nodeset

ノードセットでのノードの順番を逆順にします。 この基本的なコンバータは、逆順のドキュメントオーダーを実装するために 必要です。(XPath勧告を参照して下さい。)

Function: node-trace title
 node-trace:: String -> Converter

(node-trace title)は、それ自身を返すコンバータです。 また、自身が適用されるノードやノードセットを、’title’という プリフィックスを付けてプリントします。 このコンバータは、デバッグの際にとても便利です。

コンバータの組み合わせに続くものは、コンバータを一変させる、 あるいはコンバータのシーケンスを1つの強力なコンバータにつなぎ合わせる 高階関数です。そのゴールは、XPathのロケーションパスに対応する コンバータとなることです。

別の観点から見ると、コンバータは、コンバータ群の適用の固定され 名前の付いたパターンとみなせます。 以下に挙げるのは、XPathのロケーションパスの仕様を実装する そのようなパターンの完全なセットです。 結局のところ、これら全てのコンビネータはいくつかの基本的なブロック、 通常の関数的なコンポジション、map-unionとfilterアプリケータ、 ノードセットユニオンなどから構築することができます

Function: select-kids test-pred?
select-kids:: Pred -> Node -> Nodeset

ノードを与えると、述語(実際はコンバータ)を満足するその子要素の (順序付けられた)サブセットを返します。

select-kids:: Pred -> Nodeset -> Nodeset

上と同じですが、ノードセットの全てのノードの子要素から選択します。

Function: node-self pred
 node-self:: Pred -> Node -> Nodeset, or
 node-self:: Converter -> Converter

select-kidsに似ていますが、自身をその子要素に適用するのでは なく、ノードそれ自身に適用します。 結果のノードセットは、1つのコンポーネントを含むか、 空(ノードが述語を満足しない場合)になります。

Function: node-join . selectors
 node-join:: [LocPath] -> Node|Nodeset -> Nodeset, or
 node-join:: [Converter] -> Converter

上のタイトルコメントで説明されるようなロケーションステップ あるいはロケーションパスのシーケンスをつなぎ合わせます。

Function: node-reduce . converters
 node-reduce:: [LocPath] -> Node|Nodeset -> Nodeset, or
 node-reduce:: [Converter] -> Converter

コンバータの通常の関数的なコンポジションです。 見方を変えると、((apply node-reduce converters) nodeset)(foldl apply nodeset converters)と等価です。 すなわち、コンバータのリストをノードセットをseedとして畳み込みや分解 を行うようなものです。

Function: node-or . converters
 node-or:: [Converter] -> Converter

このコンビネータは、全てのコンバータを与えられたノードに適用し、 それらの結果のユニオンを作ります。 このコンビネータは、XPathのロケーションパスでの’|’オペレーション であるユニオンに対応します。

Function: node-closure test-pred?
 node-closure:: Converter -> Converter

述語としてのコンバータを満足するノードの全ての子孫を選択します。 このコンビネータはselect-kidsに似ていますが、孫要素やその 子要素達にも適用を行います。 このコンビネータは、XPathの軸である“descendant::”を実装します。 概念的には、このコンビネータは以下のように表現することができます。

 (define (node-closure f)
      (node-or
        (select-kids f)
	 (node-reduce (select-kids (ntype?? '*)) (node-closure f))))

この定義は、字面の通り、フィックスポイントのような何かで、 永久に実行し続けます。しかし、いつかは(select-kids (ntype?? '*)) が空のノードセットを返すことは明白です。その時点では、以降の イテレーションはその結果に影響を及ぼさず停止されることができます。


Next: , Previous: , Up: SXMLクエリ言語   [Contents][Index]

12.45.2 SXPathクエリ言語

Function: sxpath abbrpath . ns-binding

Evaluates an abbreviated SXPath

 sxpath:: AbbrPath -> Converter, or
 sxpath:: AbbrPath -> Node|Nodeset -> Nodeset

AbbrPathはリストです。これは、以下の書き換えルールに従って 完全なSXPathに変換されます。

 (sxpath '()) -> (node-join)
 (sxpath '(path-component ...)) ->
                (node-join (sxpath1 path-component) (sxpath '(...)))
 (sxpath1 '//) -> (node-or
                     (node-self (ntype?? '*any*))
                     (node-closure (ntype?? '*any*)))
 (sxpath1 '(equal? x)) -> (select-kids (node-equal? x))
 (sxpath1 '(eq? x))    -> (select-kids (node-eq? x))
 (sxpath1 '(or@ ...))  -> (select-kids (ntype-names??
                                          (cdr '(or@ ...))))
 (sxpath1 '(not@ ...)) -> (select-kids (sxml:invert
                                         (ntype-names??
                                          (cdr '(not@ ...)))))
 (sxpath1 '(ns-id:* x)) -> (select-kids
                                      (ntype-namespace-id?? x))
 (sxpath1 ?symbol)     -> (select-kids (ntype?? ?symbol))
 (sxpath1 ?string)     -> (txpath ?string)
 (sxpath1 procedure)   -> procedure
 (sxpath1 '(?symbol ...)) -> (sxpath1 '((?symbol) ...))
 (sxpath1 '(path reducer ...)) ->
                (node-reduce (sxpath path) (sxpathr reducer) ...)
 (sxpathr number)      -> (node-pos number)
 (sxpathr path-filter) -> (filter (sxpath path-filter))

sxpathには、いくつかのラッパ関数があります。

Function: if-sxpath path

sxpathは、常にリストを返し、それはSchemeでは#tとなります。 if-sxpathは、空リストの代わりに#fを返します。

Function: if-car-sxpath path

もし存在すれば、最初に見つかったノードを返します。 そうでなければ、#fを返します。

Function: car-sxpath path

もし存在すれば、最初に見つかったノードを返します。 そうでなければ、空リストを返します。

Function: sxml:id-alist node . lpaths

与えられたノードについて、(ID_value . element)の ペアのリストをインデックスとして構築します。 lpathsは、タイプIDの属性のロケーションパスです。


Previous: , Up: SXMLクエリ言語   [Contents][Index]

12.45.3 SXPathの拡張

W3CのXPathコア関数ライブラリのSXML版です。

Function: sxml:string object

XPathのstring関数(XPath勧告のセクション4.2)に対応するものです。 与えられたオブジェクトを文字列に変換します。 注意:

  1. ノードセットを変換する時は、ドキュメントオーダーは保持されません。
  2. number->string関数は、その結果をXPath勧告の仕様とは少し違った フォームで返します。
Function: sxml:boolean object

XPathのboolean関数(XPath勧告のセクション4.3)に対応するものです。 引数を真偽値に変換します。

Function: sxml:number obj

XPathのnumber関数(XPath勧告のセクション4.4)に対応するものです。 引数を数値に変換します。 注意:

  1. 引数は(まだ?)オプションではありません。
  2. string->numberの変換は、IEEE 754の四捨五入ではありません。
  3. NaNは、0として表現されます。
Function: sxml:string-value node

XPath勧告のセクション5.1 - 5.7にしたがって、与えられたノードの 文字列値を返します。

Function: sxml:node? node

XPathの仕様2.3にしたがい、このテストはいかなるXPathノードに 対しても真を返します。 SXMLの補助的なリストや属性のリストは除外されます。

Function: sxml:attr-list obj

与えられたSXMLノードの属性のリストを返します。 与えられたノードが要素ではないか、属性のリストを持っていない場合は、 空リストが返されます。

Function: sxml:id id-index

SXML要素を、そのユニークなIDによって選択します(XPath勧告 4.1)。 objectを引数に取るコンバータを返します。 このobjectは、ノードセットか、’string’関数により 文字列に変換できるデータタイプです。

id-indexは、( (id-value . element) (id-value . element) ... )です。

このインデックスは、要素をそのユニークなIDによって選択するために使われます。

XPathオブジェクトの比較子:

Function: sxml:equality-cmp bool-op number-op string-op

XPathの等値比較: =!=のためのヘルパです。 bool-opnumber-op’string-opはそれぞれ、 真偽値、数値、文字列のペアのための比較子です。

Function: sxml:equal? a b
Function: sxml:not-equal? a b

XPathの等値比較: =!=に対応するもので、 デフォルトの等値テストを使います。

Function: sxml:relational-cmp op

2つのXPathオブジェクトの関係比較( <><=>= ) を作ります。 opは、比較を行う手続き: <><=>=です。

XPathの軸。 結果のノードセットにおける順序は維持されます。

Function: sxml:attribute test-pred?

属性の軸です。

Function: sxml:child test-pred?

子要素の軸です。 この関数は、’select-kids’に似ていますが、処理命令やコメント、 実体ノードについては、空の子リストを返します。

Function: sxml:parent test-pred?

親の軸です。

述語を与えると、RootNode -> Converter関数を返します。 この関数は、rootnodeに適用されると、node -> parentと なります。

このようなコンバータは、 ((sxml:parent test-pred) rootnode) を使って構築され、それが適用されたノードの親を帰します。 ノードセットに適用された場合、そのノードセットにあるノードの 親のリストを返します。 rootnodeはSXMLツリー全体のルートノードである必要はありません。 興味の対象となるブランチ(枝)のルートノードでも構いません。 parent::軸は、どんなSXMLノードにも使えます。

Function: sxml:ancestor test-pred?

祖先の軸です。

Function: sxml:ancestor-or-self test-pred?

祖先と自分の軸です。

Function: sxml:descendant test-pred?

子孫の軸です。

Function: sxml:descendant-or-self test-pred?

子孫と自分の軸です。

Function: sxml:following test-pred?

後続するものの軸です。

Function: sxml:following-sibling test-pred?

後続する兄弟の軸です。

Function: sxml:namespace test-pred?

名前空間の軸です。

Function: sxml:preceding test-pred?

先行するものの軸です。

Function: sxml:preceding-sibling test-pred?

先行する兄弟の軸です。

ポピュラーなショートカット:

Function: sxml:child-nodes nodeset
((sxml:child sxml:node?) nodeset)
Function: sxml:child-elements nodeset
((select-kids sxml:element?) nodeset)

Previous: , Up: SXMLクエリ言語   [Contents][Index]