空セレクターを持つパターン
空セレクターは <> の形、中身がない。空セレクターを持つ原子パターンは <> ... </> となる。
空セレクターはどんなノードともマッチするが、<(node)> とはまったく違う。非空であるセレクターと空セレクターは別物と考えたほうがよい。
空セレクターを持つパターンは、構文上はパターンだが、「侵入性/検索範囲/値の形式」を前置することができない。別な言い方をすると、「侵入性/検索範囲/値の形式」が前もって組み込まれている。<>...</> は:
- 検索範囲はself、ここでselfはコンテキストノード自体(それだけ)を示す検索範囲である。
- 検索範囲がシングルトンセットなので侵入性は意味が無い。どちらを指定されても同じ挙動。直接的に指定することはできない。(OrElseパターンの外側から間接的には指定できる。)
- 検索範囲がシングルトンセットなので出力が配列になることはない。常に単一値で出力。
「侵入性/検索範囲/値の形式」が組み込まれているので、それらの指定を前置して変更することができない。
<div> <>$:txt</> </>
これは、次と同値。
<div> $:txt </>
空セレクターは「透明である」と言える。コンテキストノードは、どのような評価環境にも一意的に存在する(検索範囲は空になりうるし、カレントノードも存在しないことがある)。よって、パターンマッチが失敗することは起きない。評価環境を変えずにすぐさま内容が評価されて値が求まる。
空セレクターを持つパターンは、「侵入性/検索範囲/値の形式」を組み込みで持っているので、意味的にはパターンというよりは抽出式だが、evalに渡して、eval(a, 空セレクターを持つパターン) が評価できるとする。
extractに渡すときは、「self <(node)> ... </>」と翻訳して渡す。
空セレクターが役に立ち必須となる状況はOrElseパターンの選択肢としてである。
( <tbody> * ><tr>$:text</> </> | <> * ><tr>$:text</> </> )
これをコンテキストノードがtable要素の評価環境で評価すると、
- table要素の子孫であるtbody要素の子であるtr要素の配列
- または、table要素の子であるtr要素の配列
となる。tbody要素があれば第一選択肢がヒットして、そうでなくても第二選択肢がヒットする(値は空配列かも知れないが)。
空セレクターの代わりに、self検索範囲(self軸)を表すコンビネータを導入する方法がある。仮に '=' をSelfコンビネータだとすると、<> ...</> は、= <(node)> ...</> と同じになる。しかし、原子パターンの構文はコンビネータを含まないので、OrElseの選択肢に入れることができない。この理由で、特別な構文を準備した。