この文書は、W3CのXML Path Language (XPath) 2.0 ワーキングドラフトの翻訳です。正式な版は、W3Cのサイトにある英語版であり、この翻訳ではありません。この翻訳は原文と技術的に等価なことを意図していますが, 翻訳上の誤りが存在する可能性があります。
原文はつぎのURLで参照することができます。
http://www.w3.org/TR/2002/WD-xpath20-20020816
翻訳者
Copyright © 2002 W3C® (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use, and software licensing rules apply.
XPathはXMLドキュメントの部分を処理するための言語です。
この文書は公式なW3Cのワーキングドラフトであり、W3Cのメンバーや他の関係者がレビューするためにあります。このセクションはこの文書の公開時におけるステータスについて述べています。これはドラフト文書であり、いつでも更新されたり、差し替えられたり、使われなくなったりする可能性があります。W3Cのワーキングドラフトを参照文献として使用したり、「作成中」として以外に引用することは適切ではありません。現在公開されているW3Cの技術レポートの一覧は以下のサイトにあります。
http://www.w3.org/TR/.
この文書はXSLワーキンググループとXML Queryワーキンググループの共同作業の結果であり、これらのワーキンググループはXPath 1.0 と XQuery の両方から作り出された言語であるXPath 2.0に対して、共同で責任を持っています。XPath 2.0 と XQuery 1.0 のワーキングドラフトは同じところから作られています。この2つの言語は密接に関連しており、多くの同じシンタックスやセマンティックスを持っています。この2つのワーキングドラフト内の字句の多くは同一のものを指しています。
このバージョンの文書には、エラー処理と適合性に関して新規の詳細な記述が追加されています。さらに、新しい文法に関する記述が追加され、演算子の優先順位が明示的に記述されています。新しい2つの演算子(unorderedとidiv)が追加され、4つの演算子(assert、precedes、follows、=>)が削除されています。また、cast 式と他の演算子に関する詳細なセマンティックスについの変更について記述されており、これは、H 改訂履歴にまとめられています。
この文書は作業中の段階です。まだ決定されていない問題を含んでおり、完全に安定していると考えてはいけません。この文書を基にしてプレビューの実装を作成するベンダーは、各自のリスクにより実装しなければなりません。この文書にはワーキンググループの一般的に合意された内容が反映されていますが、まだ議論中の分野も存在し、それらの部分は変更されることがあります。
この文書やその他の問題に関する一般的なコメントを歓迎します。コメントはW3C XPath/XQuery メーリングリスト public-qt-comments@w3.org に投稿してください。(このメーリングリストの内容は http://lists.w3.org/Archives/Public/public-qt-comments/ にアーカイブされています。)
XPath 2.0 は XML Queryワーキンググループ(XML Activity の一部)と XSLワーキンググループ(Style Activity の一部)の合同で定義されています。
この規格に関連する特許の開示はXSLワーキンググループの特許開示ページ(http://www.w3.org/Style/XSL/Disclosure)に記載されることがあります。
1 序論
2 基礎
2.1 式のコンテキスト
2.1.1 静的コンテキスト
2.1.2 評価コンテキスト
2.2 入力関数
2.3 式の処理
2.3.1 ドキュメント順序
2.3.2 型付き値と文字列値
2.4 型
2.4.1 型の確認
2.4.2 シーケンス型
2.4.3 型変換
2.4.3.1
原子化
2.4.3.2
有効ブーリアン値
2.4.3.3
後退変換
2.5 エラーと一致
2.5.1 エラー
2.5.2 一致
2.5.2.1
基本XPath
2.5.2.2
スキーマ・インポート・フィーチャー
2.5.2.3
静的タイピング・フィーチャー
2.5.3 動的エラーの扱い
3 式
3.1 原始式
3.1.1 リテラル
3.1.2 変数
3.1.3 丸括弧式
3.1.4 関数呼び出し
3.1.5 コメント
3.2 パス式
3.2.1 ステップ
3.2.1.1
軸
3.2.1.2
ノードテスト
3.2.2 述語
3.2.3 非短縮シンタックス
3.2.4 短縮シンタックス
3.3 シーケンス式
3.3.1 シーケンスの作成
3.3.2 シーケンスの結合
3.4 算術式
3.5 比較式
3.5.1 値比較
3.5.2 一般比較
3.5.3 ノード比較
3.5.4 順序比較
3.6 論理式
3.7 For式
3.8 条件式
3.9 量化式
3.10 シーケンス型に関する式
3.10.1 Instance Of
3.10.2 Cast と Treat
3.11 バリデート式
(訳者注:この日本語訳ドキュメントには、Appendices は含まれていません。Appendices は、原文(http://www.w3.org/TR/xpath20/)をご参照ください。)
A Grammar
A.1 Lexical structure
A.1.1 Syntactic
Constructs
A.1.2 Lexical Rules
A.2 BNF
A.3 Precedence Order
B Type Promotion and
Operator Mapping
B.1 Type Promotion
B.2 Operator Mapping
C References
C.1 Normative
References
C.2 Non-normative
References
C.3 Background
References
C.4 Informative
Material
D Glossary
E Conformance
F Backwards
Compatibility with XPath 1.0 (Non-Normative)
G XPath 2.0 and XQuery 1.0
Issues (Non-Normative)
H Revision Log
(Non-Normative)
H.1 16 Aug 2002
H.2 10 Apr 2002
H.3 20 Dec 2001
XPathの第一の目的は[XML]ドキュメントの部分を処理することです。XPathは簡潔でXMLではない文法を使用することで、URIやXMLの属性値内のXPathの使用を容易になっています。XPathはXMLドキュメントの抽象的で論理的な構造を扱い、その表面的な文法を扱っているわけではありません。この論理的な構造は、データ・モデルとして知られており、[XQuery 1.0 and XPath 2.0 Data Model]文書に記述されています。XPathはURLの記述のように、XMLドキュメントの階層構造を辿るためにパスの記述を使用していることから名づけられています。
XPathは[XSLT 2.0]や[XQuery]などのホスト言語内に埋め込まれることを想定して設計されています。XPathはマッチング(あるノードがあるパターンと一致するかどうかをテストすること)を部分集合として持ちます。このXPathの使用については[XSLT 2.0]に記述されています。
XQuery バージョン1.0はXPathバージョン2.0の拡張です。XPath2.0とXQuery1.0の両方において文法的に妥当で、正常に実行される式は、両方の言語で同じ結果を返します。これらの言語は非常に密接に関連しているため、整合性を保つためにそれらの文法と言語の記述は共通のものから作成されており、これらの規格の編集者は共同で作業を行っています。
XPathは以下の規格にも依存しており、密接に関連しています。
XPathデータモデルはXPathプロセッサーで使用可能なXMLドキュメント内の情報を定義しています。データ・モデルは[XQuery 1.0 and XPath 2.0 Data Model]で定義されています。
XPathでサポートされている関数や演算子は[XQuery 1.0 and XPath 2.0 Functions and Operators]で定義されています。
この文書はXMLで使用されたものと同じ基本的なEBNF表記を使用してXPathの文法を規定していますが、文法記号は常に頭文字が大文字となっています。特に断りがない限り、空白文字は文法内では重要ではありません。文法のプロダクションはそれぞれに記述されている特徴を合わせて生成されます。完全な文法に関しては、付録[A Grammar]にも記載されています。
この文書内の文法のプロダクションでは、非終端記号には下線を引き、リテラル文字はダブルクォートで囲まれています。かぎ括弧はA.1 Lexical structureに記述されているlexical look-ahead を使用して認識されなくてはならないトークンを囲むために使用されます。例えば、次のプロダクションは関数呼び出しの文法について記述しています。
[47] | FunctionCall |
::= | <QName "("> (Expr ("," Expr)*)?
")" |
このプロダクションは次のように読まなくてはなりません。関数呼び出しはQNameに続いて開き丸括弧で構成されます。(これらのトークンはlexial lookaheadにより一緒に認識されなくてはなりません。)開き丸括弧はに続いてオプションの引数リストがあります。引数リストは(もし存在すれば)一つあるいは複数の式から構成され、それらはコンマで区切られます。オプションの引数リストに続いて、閉じ丸括弧があります。
[編集注: この文書の将来のバージョンでは、用語(太文字)とその定義のリンクが含まれる予定です。]
XPathの基本的な構成要素は式(expression)です。この言語では、キーワードや記号や被演算子(operand)からなるさまざまな式を提供しています。一般的に、ある一つの式の被演算子は別の式です。XPathは関数言語(functional language)であり、完全に一般性をもって、ネストするさまざまな式を扱うことができます。また、XPathは強く型付けされた言語(strongly-typed language)であり、さまざまな式の被演算子や演算子、関数は指定された型に合わせなくてはなりません。
XMLのように、XPathは大文字小文字を識別します。XPathの全てのキーワードは小文字を使用します。
式の値は常にシーケンス(sequence)であり、それは順序を持つゼロまたはそれ以上の要素(item)の集まりです。要素は一つの原子値(atomic value)あるいは、一つのノード(node)です。原子値(atomic value)は[XML Schema]で定義されているXML Schema の原子型(atomic type)の値空間内の値です。(つまり、リスト型やユニオン型ではない単純型です。)ノード(node)は[XQuery 1.0 and XPath 2.0 Data Model]に記述されている7つのノードの種類(node kinds)のうちの一つに相当します。各ノードは唯一のノード識別子(node identity)を持ちます。いくつかの種類のノードは型付きの値(typed value)や文字値(string
value)や名前(name)を持ち、ノードから抽出することができます。ノードの型付きの値(typed value)はゼロあるいはそれ以上の原子値のシーケンスです。ノードの文字値(string value)はxs:string
型の値です。ノードの名前(name)はxs:QName
型の値です。
この文書では、ネームスペース接頭辞 xs:とxsi:
はXML Schema ネームスペース http://www.w3.org/2001/XMLSchema
とhttp://www.w3.org/2001/XMLSchema-instance
にそれぞれ関連付けられていると考えます。([XML Schema]に記述されています。)そして、接尾辞xf:
はXPath/XQuery関数のネームスペースhttp://www.w3.org/2002/08/xquery-functions
に関連付けられていると考えます。([XQuery 1.0 and XPath 2.0 Functions and Operators]に記述されています。)場合によって、意味が明らかで、ネームスペースが議論にとって重要ではないようなところでは、integer
やstring
のようにXML Schema に組み込まれている型名についてはネームスペースの接頭辞を省略して使用することがあります。.
ある与えられた式に対する式のコンテキスト(expression context)は、その式の結果に影響する全ての情報で構成されます。この情報は2つのカテゴリーに分類することができ、それぞれ静的コンテキスト(static context)と評価コンテキスト(evaluation context)と呼ばれます。
このセクションでは、コア関数ライブラリ内の関数を含めて、XPathの式によって使用されるコンテキストの情報について述べられています。コア関数ライブラリ以外の他の関数は付加的なコンテキスト情報を必要とする可能性があります。
ある式の静的コンテキスト(static context)は、その式を評価する前の静的な分析の間に取得することができる情報です。この情報はその式が静的エラーを含むかどうかを判断する際に使用することができます。
XPathでは、静的コンテキストの情報は、その式が処理されている言語環境によって提供される必要があります。静的コンテキストは以下の構成要素から成ります。
型例外ポリシー(Type exception policy)。これはstrict
、またはflexible
のいずれかの値です。この値は型例外(type exception)が発生したときに取られるアクションを指示します。もしこのポリシーがstrict
である場合、型例外はエラーとして扱われます。もしこのポリシーがflexible
である場合、代替変換(fallback conversion)が起こり、この代替変換が失敗したときのみエラーが発生します。
要素名と型名のデフォルト・ネームスペース。これはネームスペースURIです。このネームスペースは、要素や型名が予期されている場所に現れる接頭辞がないQNameに対して使用されます。
関数名のデフォルト・ネームスペース。これはネームスペースURIです。このネームスペースは、関数呼び出し内の関数名として現れる接頭辞がないQNameに対して使用されます。
スコープ内スキーマ定義。これは(QName、型定義)の組み合わせです。これは式の中で参照のために使用可能なタイプセットを定義します。組み込みのスキーマタイプとインポートされたスキーマのグローバルに宣言されたタイプを含みます。また、2.2 入力関数 に記述されているように、入力関数(input function)によって取り出されたドキュメントに関連するスキーマで宣言されたタイプも含む可能性があります。
編集注: タイプ定義の入力ドキュメントからのインポートはまだ論議中です。静的コンテキストが実行時の関数によって実装に依存する形で影響を受けるという考えは議論がまとまっていません。 (Issue 307参照)
スコープ内の変数。これは(QName、タイプ)のペアです。これは、式の中で参照のために宣言済みであり、使用可能な変数のセットを定義します。QName は変数の名前を表し、タイプは静的データタイプを表します。
スコープ内の照合。これは、(URI、照合)の組み合わせです。引数として照合名をとる関数呼び出しの中で使用することができる照合の名前を定義します。照合は2つの関数をサポートするオブジェクトとしてみなすことができます。1つの関数は文字列のセットを与えられると、並び替えた順にそれらの文字列を連続して返し、もう1つの関数は2つの文字列を与えられた時に、もしそれらが等しい場合にはtrueを、そうでない場合にはfalse を返すものです。
ベースURI。これは絶対(absolute)URIです。xf:document
関数で、もし関数呼び出し内で明示的にベースURIが指定されなかった場合に、読み込まれたドキュメントの相対URIを解決するときに使用されます。
式の評価コンテキスト(evaluation context)は、その式が評価されるときに使用可能な情報と定義されます。評価コンテキストは静的コンテキストを構成する全てのコンポーネントと、以下に示す付加的なコンポーネントで構成されます。
動的コンテキストの最初の3つのコンポーネント(コンテキスト要素、コンテキスト位置、コンテキスト・サイズ)は、式の焦点(focus)と呼ばれます。焦点により、式によってプロセッサーはどのノードを処理しているのかを把握することができます。
一番外側の式の焦点は式が評価される環境により提供されます。ある言語構成、特にパス式E1/E2
と述語式E1[E2]
は副式の評価を行うために新しい焦点を作成します。これらの構成要素では、E1
を評価した結果のシーケンス内の各要素に対して、E2
は一度だけ評価されます。E2
が評価される度に、それは異なる焦点で評価されます。E2
を評価する焦点は、以下では内部焦点(innner focus)と記述され、一方でE1
を評価する焦点は外部焦点(outer focus)と記述されています。内部焦点はE2
が評価されている間のみ存在します。この評価が完了すると、含まれている式の評価は元の焦点を変更せずに続けられます。[編集注: 問題216参照。]
コンテキスト要素は、現在処理されている要素です。要素は原子値あるいはノードのどちらかです。コンテキスト要素がノードの時、これはコンテキスト・ノードとも記述されます。コンテキスト要素は式".
"によって返されます。式E1/E2
やE1[E2]
が評価されるとき、E1
を評価することにより得られるシーケンス内の各要素は、E2
を評価するための内部焦点におけるコンテキスト要素となります。
xf:position()
で返されます。式E1/E2
やE1[E2]
を評価するとき、E2
を評価する内部焦点におけるコンテキスト位置は、E1
を評価して得られたシーケンス内のコンテキスト要素の位置となります。あるシーケンス内における最初の要素の位置は、常に1です。コンテキスト位置は常にコンテキスト・サイズに等しいか、それより小さい値となります。
コンテキスト・サイズは現在処理しているシーケンスの中の要素の数です。この値は、常にゼロより大きい整数値です。コンテキスト・サイズは式last()
により返されます。式E1/E2
やE1[E2]
が評価されるとき、式E2
を評価する内部焦点におけるコンテキスト・サイズは、式E1
を評価して得られたシーケンス内の要素の数になります。
動的変数。これは(QName、型、値)の組み合わせです。その式の静的コンテキスト内に、スコープ内変数として同じQNameを含みます。各QNameは対応する変数の動的タイプと値に関連付けられています。変数の値に関連付けられている動的タイプは、同じ変数に関連付けられている静的タイプより明確である可能性があります。
一般的に、変数の値はシーケンスです。変数の動的タイプと値は、XPath式が評価されているホスト言語環境により与えられます。
xf:current-date
、xf:current-time
、xf:current-dateTime
により得ることができます。照会、あるいは変形中に複数回実行されると、これらの関数は常に整合性を保つ結果を返します。
暗黙的なタイムゾーン。これは、タイムゾーンを指定されていないdate、time、dateTimeの値が比較や他の演算に使用されたときに使用されるタイムゾーンです。この値は実装時に決められるdayTimeDurationのインスタンスです。タイムゾーンの適切な値の範囲については、[ISO 8601]を参照してください。
入力シーケンス。入力シーケンスは、input
関数によってアクセスすることができるノードのシーケンスです。これは、"暗黙的な入力"と考えることができます。入力シーケンスの内容は実装に依存します。
XPathは入力データにアクセスするために、3つの関数を提供しています。これらの関数は、式がドキュメントやドキュメントの集合を参照することができる方法を提供しているために、非常に重要です。3つの入力関数はここに概略が記述されていますが、詳細は[XQuery 1.0 and XPath 2.0 Functions and Operators]に記述されています。
入力シーケンスはある式に対する評価コンテキストの一部です。ノードが入力シーケンスに割り当てられる方法は実装に依存します。例えば、ある実装では、ディレクトリ・システムから入力シーケンスに固定的にマッピングする方法を提供するかもしれませんし、他の実装では、ユーザーが入力シーケンスに対するデータソースを選択するためのグラフィカル・ユーザー・インターフェースを提供するかもしれません。また、別の実装では、UNIXスタイルのパイプをサポートし、一つの照会の出力を他の照会の入力シーケンスとすることができるかもしれません。
input
関数は、パラメーターを取らず、入力シーケンスを返します。例えば、式input()//customer
は入力シーケンスのノードの子孫である全てのcustomer
要素を返します。もし入力シーケンスが割り当てられていない場合には、入力関数は動的エラーを発生させます。
collection
関数はあるコレクション内に存在するノードを返します。コレクションはノードの任意のシーケンスです。コレクションは文字列で特定され、その文字列は妥当なURIである必要があります。例えば、式collection("http://example.org")//customer
はURIがhttp://example.org
であるコレクション内に存在するノードの子孫の全てのcustomer
要素を特定します。
document
関数は、もしその最初の引数がXMLドキュメントを参照する単一のURIを含む文字列である場合には、そのドキュメントのルートを返します。document
関数は複数のドキュメントやドキュメントのフラグメントを扱うために使用することもできます。詳細は、[XQuery 1.0 and XPath
2.0 Functions and Operators]を参照してください。
このセクションで記述されている入力関数を使用すると、入力ドキュメントやドキュメントのフラグメントにアクセスすることができます。これらのドキュメントやドキュメントのフラグメントがスキーマに関連付けられていれば、そのスキーマ内に含まれている型定義はスコープ内スキーマ定義に追加することができます。この方法は実装に依存します。
編集注:入力ドキュメントから型定義をインポートすることは、まだ議論の最中です。静的コンテキストが実装に依存する方法で実行時の関数により影響を受けるという考えは論議中です(問題307参照)。
XPathは[XQuery 1.0 and XPath 2.0 Data Model](この文書を単にデータ・モデルと呼びます。)によって定義されています。ここではノードと原子値の情報をあらわしています。XPath式が処理される前に、その式によって処理される入力ドキュメントはデータ・モデルであらわされる必要があります。例えば、XMLドキュメントは以下のステップでデータ・モデルに変換されます。
上記のステップはデータ・モデルのインスタンスを構成する一例を示しているに過ぎません。データ・モデルのインスタンスはリレーショナル・データベースから直接合成することも可能ですし、他の方法で構成することも可能です。XPathはデータ・モデルに関する処理を定義しており、そのデータ・モデルのインスタンスがどのように構成されるかについては何の制約も設けていません。
データ・モデルの各要素ノードや属性ノードにはその動的タイプを示す注釈をつける事ができます。データ・モデルが入力XMLドキュメントから得られた場合には、要素や属性の動的タイプはスキーマの妥当性検証により得られます。要素や属性の動的タイプは値の範囲を示しています。例えば、version
という名前の属性はxs:decimal
という動的タイプを持つことができますが、それはdecimalの値を持っていることを示しています。
属性の値は属性ノード内に直接表示されます。タイプがunknownである属性ノード(スキーマが存在しないドキュメントで起こる可能性があります)はxs:anySimpleType
という動的タイプを注釈として持ちます。
要素の値はその要素ノードの子として表示され、それはテキスト・ノードや他の要素ノードです。要素ノードの動的タイプは、その子のテキスト・ノードの値をどのように解釈するかを示します。タイプがunknownである要素(スキーマが存在しないドキュメントで起こる可能性があります。)はxs:anyType
という動的タイプを注釈として持ちます。
データ・モデルの原子値も動的タイプの注釈を持ちます。unknownタイプの原子値はxs:anySimpleType
という注釈を持ちます。ある環境下(算術演算の実行中など)では、xs:anySimpleType
の型を持つ原子値の値は特定された型(xs:double
など)にキャストされる可能性があります。
この文書はどのようにそれぞれの種類の式が処理されるかについて記述しています。各式について、被演算子と結果はデータ・モデルのインスタンスです。XMLドキュメントをデータ・モデルに変換する詳細に関しては、[XQuery 1.0 and XPath 2.0 Data Model]に記述されています。データ・モデルのインスタンスのXMLドキュメントに対する変換は、現在のところ特に決まっていません。
ドキュメント順序、型付き値、文字列値という用語がここで述べられていますが、これらは式の処理を行う上で非常に重要です。
ドキュメント順序は言語プロセッサーが把握している全てのノード間で完全な順序付けを定義します。あるドキュメントに対して、ドキュメント・ノードが最初のノードになり、要素ノード、テキスト・ノード、コメント・ノード、処理命令ノードがドキュメントのXMLの形式(エンティティーの展開後)において表示される順序で続きます。要素ノードはその子の前に出現します。要素のネームスペース・ノードは要素ノードの直後に続きますが、順序は実装に依存します。要素の属性ノードはネームスペース・ノードの直後に続きますが、これも順序は実装に依存します。
別個のドキュメントのノードの相対的な順序は実装に依存しますが、ある照会や変形の中では一定です。つまり、2つの別のドキュメントAとBがあった場合、ドキュメントAのあるノードがドキュメントBのあるノードの前にあった場合、ドキュメントAの全てのノードはドキュメントBの全てのノードの前にあります。ドキュメントではない浮動的なノード間の相対的な順序は実装に依存します。
要素ノード、属性ノード、テキスト・ノードは、それぞれdata
関数とstring
関数を呼び出すことにより抽出される型付き値(typed value)と文字列値(string value)を持つことができます。あるノードの型付き値は原子値のシーケンスであり、あるノードの文字列値は文字列です。要素ノードと属性ノードは型注釈(type annotation)も持ちます。これは、スコープ内スキーマ定義で定義されるQNameです。
各種のノードの型付き値と文字列値は[XQuery 1.0 and XPath 2.0 Data Model]内のdm:typed-value
とdm:string-value
アクセッサで定義されています。特に、
テキスト・ノードの型付き値は文字列値と同じで、xs:anySimpleType
のインスタンスと同じです。
もし、属性ノードの型注釈がxs:anySimpleType
であった場合、その型付き値は文字列値と同じで、xs:anySimpleType
のインスタンスと同じです。そうでない場合、その型付き値は[XQuery 1.0 and XPath 2.0 Data Model]に記述されているように、スキーマの妥当性検査に一致するような方法でその文字列値と型注釈から得られます。
例:A2は型注釈IDREFS
を持つ妥当な属性で、IDREF
から得られるようにリスト型です。その文字列値は"bar baz faz
"です。A2の型付き値は3つの原子値("bar
"、"baz
"、"faz
")のシーケンスであり、それぞれの型はIDREF
です。
もし、要素ノードの型注釈がxs:anyType
である場合、その型付き値は文字列値と等しく、xs:anySimpleType
のインスタンスと等しくなります。そうでない場合は、その型付き値は、[XQuery 1.0 and XPath 2.0 Data Model]に記述されているように、スキーマの妥当性検査に一致するような方法でその文字列値と型注釈から得られます。もし、ある要素の型注釈が複合内容を持つ型を示していた場合(つまり、その型が副要素を持つことができる場合)、その型付き値は未定義となり、そのような要素にdata
関数が使用された場合にはエラーを発生させます。
例:E2はhatsizelist
の型注釈を持つ妥当な要素ノードです。これは、hatsize
のタイプを持つ要素のシーケンスとして定義される内容を持つ複合型で、hatsize
はxs:integer
から導出されます。E2の文字列値は"7 8 9
"です。E2の型付き値は3つの値(7
、8
、9
)のシーケンスで、それぞれの型はhatsize
です。
例:E3はweather
の型注釈を持つ妥当な要素ノードで、副要素を持つことができる複合型です。E3の文字列値は"hot
"です。E3はたまたま副要素を持っていないにも関わらず、その型は副要素を持つことができるため、型付き値は未定義となります。
XPathは[XML Schema]を基本とした型のシステムを持つ強く型付けされた言語です。XPathの組み込み型は、XMLのノードの種類(要素ノード、属性ノード、テキストノードなど)、[XML Schema]の組み込みの原子タイプ(atomic type)(xs:integer
やxs:string
など)、特別に導出されるxf:dayTimeDuration
とxf:yearMonthDuration
([XQuery 1.0 and XPath 2.0 Functions and Operators]に記述されている)型を含みます。付加的な型定義はスコープ内スキーマ定義を通じて言語環境からインポートされる可能性があります。
ある値の型が使用されているコンテキストに対して適切ではない時、型例外(type exception)が発生します。XPath 2.0 を基本としている言語は2.4.3.3 後退変換に記述されているように、strict
またはflexible
ポリシーによって型例外を扱う必要があります。
XML Schema のように、XPathは匿名型(anonymous types)と名前付き型(named types)を区別します。名前付き型には、全ての組み込み型と全ての型定義に名前を含むユーザー定義単純型とユーザー定義複雑型が含まれます。例えば、名前付き型は以下の中の一つの方法で関連付けられることができます。
リテラル値は名前付き型を持つことができます。例えば、47という値の型はxs:integer
です。
[XQuery 1.0 and XPath 2.0 Functions and Operators]に記述されているコンストラクター関数は名前付き型の値を返します。例えば、xs:date("2002-5-31")
はxs:date
の型の値を返します。
データ・モデルのインスタンスが妥当性が検証されたドキュメントから構成された時、スキーマ・プロセッサーによってデータ・モデル内に割り当てられた型の名前が保存されます。
validate
式は照会内でスキーマに対する妥当性を検証しますが、スキーマ・プロセッサーが行うのと同じ方法で型名を割り当てます。
cast
式は特定の名前付き型を持つ原子値を作成します。
data()
などの関数は、ドキュメントのノードから型付き値を取り出し、それらの値の名前付き型を保存します。
XPathの型のシステムは[XQuery 1.0 Formal Semantics]に正式に定義されています。このセクションはユーザー側の視点から、型の概要を示します。
XPathは分析フェーズ(analysis phase)と評価フェーズ(evaluation phase)と呼ばれる2つのフェースの処理を定義します。
分析フェーズ(analysis phase)は、照会式自体と静的コンテキストに依存します。分析フェーズは入力データには依存しません。分析フェーズにおける型の確認の目的は、早く型のエラーを検知し、照会結果の型を計算することです。
分析フェーズの間に、各式には静的型(static type)が割り当てられます。いくつかの場合には、静的型は式の辞書的な形から得られます。例えば、リテラル値である5の静的型はxs:integer
です。他の場合には、式の静的型はその被演算子の静的型に基づいた規則に従って推測されます。例えば、式size < 5
の静的型はxs:boolean
です。式の静的型は名前付き型または構造的な記述のどちらかです。例えば、xs:boolean?
はxs:boolean
型が任意に出現することを示しています。さまざまな式の静的型を推測する規則については、[XQuery 1.0 Formal Semantics]に述べられています。分析フェーズの間、式の被演算子がその被演算子に適切ではない静的型を持つことがわかった場合、静的型エラーが発生します。もし、静的型の確認がエラーなしで実行され、ある式にTという静的タイプを割り当てた場合、その式を妥当な入力データに対して実行すれば、型Tを持つ値を生成するか、あるいは動的型エラーが発生するかのどちらかであることが保証されます。
評価フェーズ(evaluation phase)は、分析フェーズ(analysis phase)が成功して完了した後にのみ実行されます。評価フェーズは入力データと評価される式と評価コンテキストに依存します。評価フェーズの間、動的型が値が計算されるたびに割り当てられます。値の動的型は構造型("integerのシーケンス"など)、または名前付き型のどちらかです。値の動的型はその値を計算する式の静的型より明確である可能性があります。(例えば、ある式の静的タイプがゼロまたはそれ以上のintegerまたはstring"であったとすると、実行時にその値は"integer"という動的型を持つ可能性があります。)ある式の被演算子がその被演算子に適切ではない動的型を持つことがわかった場合、型例外が発生します。
ある式に対して、たとえいくつかの妥当な入力データに対する評価が成功するとしても、式の分析により静的型エラーが発生する可能性はあります。例えば、ある式はパラメータとして要素をとる必要がある関数を含むとし、分析フェーズはその関数のパラメータの静的型としてオプショナルな要素であると推測したとします。この場合オプショナルな要素が存在する入力データに対しては関数呼び出しは成功するにも関わらず、結果は静的エラーとなると考えられます。
ある式に対して、分析フェーズで静的エラーが発生していないにもかかわらず、動的エラーを発生させることも可能です。例えば、式が文字列をintegerにキャストする式を含んでおり、それは静的に妥当であるとします。しかし、もし実際の文字データが実行時にintegerにキャストできなかった場合には、結果として動的エラーとなります。同様に、スキーマがないドキュメントから取り出された値に対する算術演算を行うことを考えます。これは静的エラーではありません。しかし、実行時にもし値が正常に数値型にキャストできない場合には、動的エラーが発生します。
もし、実装により式が動的エラーを発生させる必要があると静的分析が決定することができる場合(例えば、妥当なdecimalの値ではない文字定数からdecimalの値を構成しようとしている場合など)、その実装はこのエラーを(評価フェーズと同様に)分析フェーズで報告することができます。
XPath式で型を参照する必要があるとき、以下の文法が使用されます。この文法のプロダクションは、XPathの値であるシーケンスの型について記述しているため、"シーケンス型"と呼ばれます。
[51] | SequenceType |
::= | (ItemType OccurrenceIndicator) | "empty" |
[52] | ItemType |
::= | (("element" | "attribute") ElemOrAttrType?) |
[53] | ElemOrAttrType |
::= | (QName (SchemaType | SchemaContext?)) | SchemaType |
[54] | SchemaType |
::= | <"of" "type"> QName |
[48] | SchemaContext |
::= | "in" SchemaGlobalContext ("/" SchemaContextStep)* |
[49] | SchemaGlobalContext |
::= | QName | <"type" QName> |
[50] | SchemaContextStep |
::= | QName |
[55] | AtomicType |
::= | QName |
[56] | OccurrenceIndicator |
::= | ("*" | "*" | "+"
| "?")? |
ここにXPath式で使用されるシーケンス型の例をいくつか示します。
xs:date
は組み込みのスキーマ型であるdate
を参照します。
attribute?
はオプショナルな属性を参照します。
element
はいずれかの要素を参照します。
element office:letter
は特定の名前を持つ要素を参照し、それはその名前に対するスキーマ定義に対して妥当性が確認されています。
element of type po:address+
はある型のスキーマ定義に対して妥当性が確認された一つまたはそれ以上の要素を参照します。
node*はゼロまたはそれ以上の任意の型の
ノードのシーケンスを参照します。
item*はゼロまたはそれ以上のノードまたは原子値を参照します。
照会を実行する間、値がシーケンス型文法を使用して宣言された型と一致しているかどうかを決定する必要がある場合があります。この処理はシーケンス型マッチング(Sequence Type matching)として知られています。例えば、instance of
式はもしある値がある型に一致していればtrue
を返し、そうでない場合にはfalse
を返します。
値とシーケンス型におけるシーケンス型マッチングは以下のように実行されます。
もし、シーケンス型がemptyであったら、値が空シーケンスである場合のみマッチングは成功します。もし、シーケンス型がOccurrenceIndicatorを持たない要素型(Item Type)である場合、値が正確に1つの要素(item)のみを含み、その要素が要素型(以下参照)と一致する場合にのみマッチングは成功します。もし、シーケンス型が要素型とOccurrenceIndicatorを持つ場合、値の中の要素の数がOccurrenceIndicatorと一致し、各要素が要素型と一致する場合にのみマッチングは成功します。つまり、空シーケンスである値はOccurrenceIndicatorが*または?である任意のシーケンス型に一致します。
OccurrenceIndicator は以下のように、シーケンス内の要素の数を示します。
?はゼロあるいは1つの要素を示します。
ある値をある要素型にマッチングさせる処理は以下のように実行されます。(要素はノードまたは原子値であることを思い出してください。)
要素型item
は任意の要素に一致します。例えば、item
は原子値1
や要素<a/>
に一致します。
以下の要素型は原子値と一致します。
atomic value
は任意の原子値に一致します。
xs:decimal
は値12.34
(decimalリテラル)と一致します。また、shoesize
がxs:decimal
から導出された原子型である場合には、動的型がshoesize
である値とも一致します。
untyped
は、その最も明確な型がxs:anySimpleType
である原子値に一致します。
次の要素型はノードに一致します。
node
は任意のノードに一致します。
text
は任意のテキスト・ノードに一致します。
processing-instruction
は任意の処理命令ノードに一致します。
comment
は任意のコメント・ノードに一致します。
document
は任意のドキュメント・ノードに一致します。
element
はある要素ノードに一致します。オプションとして、element
には、ElemOrAttrType が続き、さらにノードに対して制限を設けることができます。(下記参照)
attribute
はある属性ノードに一致します。オプションとして、attribute
には、ElemOrAttrType が続き、さらにノードに対して制限を設けることができます。(下記参照)
ElemOrAttrType は、以下のように要素や属性の名前や型に対して制限を設けるために使用することができます。
ElemOrAttrType の一つの形として、"of type
"という語句を指定すると、要素ノードあるいは属性ノードの必須型(required type)を指定します。必須型はスコープ内スキーマ定義に定義された単純型あるいは複合型のQNameでなくてはなりません。要素や属性の型注釈が必須型と同じであるか、(スコープ内スキーマ定義により)必須型から導出されることが自明である場合にのみ一致は成功します。例えば、element of type Employee
は妥当で型注釈Employee
を受け取る要素ノードに一致します。同様に、attribute of type xs:integer
は妥当で型注釈xs:integer
を受け取る属性ノードに一致します。
もう一つのElemOrAttrTypeの形は単純なQNameで、その要素や属性の必須名(required name)として解釈されます。そのQNameはスコープ内スキーマ定義にある要素名あるいは属性名でなくてはなりません。ある要素や属性が必須名を持ち、その必須名に対するスキーマ定義に対して一致する場合にのみ、一致は成功します。これは、以下のいずれかの方法で確認されます。
もし、必須名に対するスキーマ定義が名前付き型である場合、その要素や属性の型注釈は、その名前付き型と同じであるか、あるいは(スコープ内スキーマ定義により)その名前付き型から得られることが自明である必要があります。例えば、スキーマが要素名location
の型としてState
を持つと宣言していると仮定します。シーケンス型element location
は、その名前がelement location
で、その型注釈がState
であるか、State
から得られる名前付き型であるような要素にのみ一致します。
もし、必須名に対するスキーマ定義がanonymous(unnamed)型定義である場合には、その要素や属性の実際の内容は構造としてこの型定義に従わなくてはなりません。例えば、shippingAddress
という名前の要素に対して、スキーマがstreet
要素と、それに続くcity
要素から構成されるanonymous複合型を宣言していると仮定します。シーケンス型element shippingAddress
は、その名前がshippingAddress
で、その内容がstreet
要素とそれに続くcity
要素で構成されるような要素にのみ一致します。
要素が必須名を持たなくてはならないという制約は、その要素が妥当であり、先頭のノードが必須名を持つ代理グループ(substitusion group)のメンバーである場合に、満たされていると考えられます。代理グループについては、[XML Schema]に記述されています
上の2つの形のElemOrAttrTypeは要素や属性の必須名と必須型の両方を指定するために結合して使用することができ、element person of type Employee
あるいは、attribute color of type xs:integer
のようになります。この形は、例えば必須名に関連付けられているスキーマ型よりも明確な必須型を指定するような場合に使用することができます。
いくつかの場合では、要素ノードや属性ノードの必須名はローカルに宣言される(つまり、あるスキーマの複合型やの中で宣言される)ことがあります。このような場合、ElemOrAttrType はスキーマ・コンテキストを指示し、その中で必須名が解釈できるようにします。例えば、element shippingAddress in invoice/customer
は、要素名shippingAddress
のスキーマ定義に対して一致する要素ノードに一致します。なぜなら、invoice
要素の内部のcustomer
要素の内部で解釈されるためです。スキーマ・コンテキストの最初のQNameはスコープ内スキーマ定義になくてはなりません。
式の中にはその被演算子が予期している型に完全に一致する必要がないものもあります。例えば、関数のパラメータや戻り値は特定の型を予期していますが、ノードからの原子値の取り出し、数値のプロモーション、型がない値の暗黙的なキャスティングなどの特定の型変換が自動的に実行されます。関数のパラメータと戻り値に対する変換規則は3.1.4 関数呼び出しで議論されています。その他の特殊な変換規則を提供する演算子には、3.4 算術式で議論されている算術演算子や3.5.1 値比較で議論されている値の比較があります。
型変換は原子化(atomization)と呼ばれるプロセスに依存することがあります。原子化はオプショナルな原子値が予期されるときに使用されます。ある値に原子化を適用すると、結果は単一の原子値か空シーケンスか、型例外です。原子化は以下のように定義されます。
値が単一の原子値か空シーケンスであった場合、原子化は単にその値を返します。
値が単一のノードであった場合、そのノードの型付き値が抜き出されて返されます。しかし、型付き値が一つ以上の要素を持つシーケンスであった場合、型例外が発生します。
その他の場合には、原子化は型例外を発生させます。
原子化は以下の式の型を処理するときに使用することができます。
比較式
関数呼び出しと返り値
キャスト式
もし要素のシーケンスがブーリアン値が予期される部分にあたったら、有効ブーリアン値を見つける必要があります。シーケンスの有効ブーリアン値は以下のように定義されています。
シーケンスがemptyであった場合、有効ブーリアン値はfalse
です。
シーケンスが単一のxs:boolean
型の原子値を含む場合、この値はそのシーケンスの有効ブーリアン値です。
true
です。
シーケンスの有効ブーリアン値は以下の式の型を処理する間に計算される可能性があります。
論理式(and、or)
xf:not
関数
条件式(if)
量化式(some
、every
)
型例外(type exception)が発生した場合、取られるアクションについては、XPath式が評価されている言語環境に依存します。言語環境はstrict
かflexible
のどちらかの型例外ポリシーを選択することができます。ポリシーがstrict
である場合、型例外は動的エラーとして扱われます。ポリシーがflexible
である場合、後退変換(fallback conversion)と呼ばれるある決まった一組の規則を適用することにより、言語環境は型例外を扱う必要があります。後退変換の目的はXPath
バージョン1.0の振る舞いに対する下位互換性を提供するためです。
これは、型変換について、他よりも寛容である言語環境が存在することを意味します。一般的に、XPath式は後退変換に依存しない時のみある言語環境から別の言語環境に移行可能です。しかし、ある式が2つの言語環境においてエラーなく評価される場合、それは常に同じ結果を返します。
ある値が必要な型に一致しない時、型例外が発生します。後退変換を実装する言語環境は、以下の規則を適用することでこの不一致を解決しなくてはなりません。
もし、必須型が原子型や単一のノード以外である場合、動的エラーが発生します。
もし、必須型がブーリアンであり、値が空シーケンスである場合、値はブーリアンのfalse
に変換されます。
もし、必須型がブーリアンであり、値が少なくとも1つのノードを含むシーケンスである場合、値はブーリアンのtrue
に変換されます。
もし、必須型がノードであり、シーケンスの最初の要素がノードである場合、最初の要素のみが保持されます。もし、必須型がノードであり、シーケンスの最初の要素がノードではない場合、動的エラーが発生します。
上記以外で、もし値が1つ以上の要素を含むシーケンスである場合、最初の要素のみが保持されます。もし、この要素がノードである場合、その型付き値が抜き出されます。もし、ノードの型付き値が1つ以上の原子値のシーケンスである場合、これらの原子値の最初のもののみが保持されます。(与えられた、あるいは抜き出された)結果の原子値は以下の表の規則に従って、必須型に変換されます。
ブーリアン値 | 文字列値 | 数値 | その他の原子値 | |
---|---|---|---|---|
ブーリアン値 | N/A | ブーリアンの値falseは文字列のfalse に変換されます。ブーリアンの値trueは文字列のtrue に変換されます。 |
ブーリアンのtrueは1 に変換されます。ブーリアンのfalseは0 に変換されます。 |
動的エラー |
文字列値 | 'true'や'1'はtrue、'false'や'0'はfalseとなります。その他の場合、文字列値がemptyの場合にはfalseが返り、そうでない場合にはtrueが返ります。 | N/A | その特定の数値型に対する数値コンストラクタが使用され、文字列値が変換されます。 | [XQuery 1.0 and XPath 2.0 Functions and Operators]文書で定義されている特定の型に対する適切な文字列コンストラクタが使用されます。 |
数値 | 0、+0、-0、NaNはブーリアンfalseに変換されます。その他はブーリアンtrueに変換されます。 | データモデルに定義されているように、原子値の文字列値を使用します。 | N/A | [XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されている表を使用して、その原子型に値をキャストすることを試みます。失敗すると、動的エラーが発生します。 |
その他の原子値 | [XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されている表を使用して、値をブーリアンにキャストすることを試みます。失敗すると、動的エラーが発生します。 | [XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されている表を使用して値を文字列値にキャストすることを試みます。失敗すると、動的エラーが発生します。 | [XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されている表を使用して値を数値にキャストすることを試みます。失敗すると、動的エラーが発生します。 | [XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されている表を使用して、値を原子型にキャストすることを試みます。失敗すると、動的エラーが発生します。 |
編集者注:この表の値は[XQuery 1.0 and XPath 2.0 Functions and Operators]内のキャストと常に一致する必要があります。一致しないことがある場合、[XQuery 1.0 and XPath 2.0 Functions and Operators]が優先します。
編集者注:このセクションはXML Queryワーキング・グループによって承認されていますが、まだXSLTワーキング・グループにより議論されています。この議論の結果として、XPathの文法や意味が変わる可能性があります。
2.4.1 型の確認で述べられているように、XPathには分析フェーズが定義されており、それは入力値には依存しません。また、評価フェーズが定義されており、それは入力データに依存します。
分析フェーズの結果は成功か、1つ以上の静的エラーとなります。静的エラーの中には、静的型エラーがあり、式の静的型が出現するコンテキストに対して正しくない場合に発生します。静的エラーという用語には、文法エラーなどのように型とは関係のないエラーも含まれます。静的エラーが報告される方法は実装に依存します。
評価フェーズの結果は結果の値か、動的エラーとなります。動的エラーには、動的型エラーがあり、式の動的型が出現するコンテキストに対して正しくない場合に発生します。動的エラーという用語には、数値オーバーフローのように型とは関係のない動的エラーも含まれます。実装が値を返す場合、その値は[XQuery 1.0 Formal Semantics]に定義されている動的規則と一致していなくてはなりません。
[XQuery 1.0 Formal Semantics]には、静的エラーと動的エラーの定義があります。それらのエラーに加えて、XPathの実装は、分析フェーズ中あるいは評価フェーズ中に、その実装に依存する警告を発生させることが可能です。警告をどう発生させ、どう扱うかは実装に依存します。
XPathは基本XPath(Basic XPath)という名前の基本的な一致レベルを定義し、オプションとしてスキーマ・インポート・フィーチャー(Schema Import Feature)と静的タイピング・フィーチャー(Static Typing Feature)と呼ばれる2つの機能を定義します。一致の実装は基本XPathの要件を満たさなくてはなりません。また、オプション機能のどちらかあるいは両方を提供することもできます。
基本XPathに一致する実装はXPath言語を完全に実装をしなくてはならず、以下の制限に従う必要があります。
基本XPathの実装において、スコープ内スキーマ定義は48の事前に定義された固定の型定義で構成されます。この中には、[XML Schema]で定義されている44の組み込みデータ型と、xf:yearMonthDuration
、xf:dayTimeDuration
、xs:anySimpleType
、xs:anyType
の4つの追加の型が含まれます。
xs:anyType
にマップされます。(当然、PSVIからのマッピングは照会データ・モデルのインスタンスが構成される一つの方法に過ぎず、他の方法も可能です。)
シーケンス型が上に挙げた48の事前定義された型ではない原子型を含む場合、基本Pathの実装は静的エラーを発生させます。
シーケンス型がElemOrAttrTypeを含む場合、基本XPathの実装は静的エラーを発生させます。
式の処理がある値の型に依存し、その型が上に挙げた48の事前定義された型ではない型である場合、基本XPathの実装は動的エラーを発生させます。
基本XPathの実装は分析フェーズで静的型エラーを発生させる必要はありません。ある式が1つ以上の型に関係のない静的エラーを含む場合、基本XPathの実装は分析フェーズにおいて少なくともこれらの静的エラーの一つを発生させなくてはなりません。分析フェーズが成功し、評価フェーズにおいて1つ以上の動的エラーが発生した場合、基本XPathの実装は少なくともこれらの動的エラーの一つを発生させなくてはなりません。
静的タイピング・フィーチャー(Static Typing Feature)は基本XPathの規則6に示されている制限を除外します。このフィーチャーを含む実装は静的型エラーを検知する必要があります。ある式が1つ以上の静的型エラーを含んだ静的エラーを含む場合、静的タイピングの実装は分析フェーズにおいて少なくともこれらの静的エラーの一つを発生させなくてはなりません。
編集者注:ワーキング・グループは、現在さまざまなXPathのフィーチャーの間の関係について議論しています。(例えば、式があるフィーチャーAを持つ実装で実行に成功した場合、フィーチャーB を持つ実装でも実行に成功するでしょうか?)また、ワーキング・グループは"型の堅牢性"について議論しています。(つまり、静的タイピング・フィーチャーが実装されてある式が静的エラーを発生しなかった場合、評価フェーズにおいてどのような振る舞いが保証されるのでしょうか?)編集者はこの文書の将来のバージョンにこの問題に関するさらに多くの資料を含めることができると考えています。(問題308参照)
この文書に記述されているものを除いて、もしある式の被演算子が動的エラーを発生させる場合には、その式も動的エラーを発生させます。もし、ある式が妥当であり、ある値を返す場合、あるいは動的エラーを発生させる場合、実装はその値を返すか動的エラーを発生させるかを選択することができます。例えば、論理式expr1 and expr2
は、どちらかの被演算子がfalse
を返す場合、値false
を返すことができます。あるいはもしどちらかの被演算子が動的エラーを発生させる場合、この論理式は動的エラーを発生させることができます。
もし、ある式の1つ以上の被演算子がエラーを返す場合、実装はその式によってどのエラーを発生させるのかを選択することができます。例えば、この式
($x div $y) + xsd:decimal($z)
において、($x div $y)
とxsd:decimal($z)
の両方はエラーを発生させる可能性があります。実装は"+
"式によりどのエラーが発生するかを選択することができます。一度ある被演算子がエラーを発生させると、実装は他の被演算子の評価をする必要はありませんが、評価しても構いません。
動的エラーはエラー値(error value)を持ち、これは単一の要素あるいは空シーケンスです。例えば、エラー値はintegerや文字列やQNameや要素である可能性があります。実装はアプリケーション定義のエラー・ハンドラーがエラー値を処理し、診断メッセージを生成することができるような仕組みを提供することができます。エラー・ハンドラーがない場合、エラー値の文字列値(string-value)をエラーメッセージとして直接使用することができます。
動的エラーは組み込みの関数や演算子によって発生する可能性があります。例えば、input
関数は、もし評価コンテキストにおいて入力シーケンスが定義されていない場合にはエラーを発生させます。
エラーはxf:error
関数を明示的に呼ぶことにより発生させることができます。これは、エラーのみを発生させ、値を返すことはありません。xf:error
関数はオプショナルな要素をパラメータとしてとり、それはエラー値として使用されます。例えば、以下の関数呼び出しはエラー値が文字列である動的エラーを発生させます。
xf:error(xf:concat("Unexpected value ", $v))
このセクションは基本的な種類のXPath式を紹介します。それぞれのXPath式はPathExpr
などの名前を持っており、式を定義する文法プロダクションの左側で紹介されます。XPathは構成言語(composable
language)であるため、それぞれの式は高い優先順位の演算子を持つ他の式で定義されます。この方法で、演算子の優先順位は文法中に明示的に表されます。
もっとも単純な種類の式が最初に紹介されます。その後、複雑な式が紹介されます。この表示の順番は演算子の優先順位と一致しません。完全な文法は付録[A Grammar]に記述されています。
最も高いレベルの式はExprSequenceで、3.3.1 シーケンスの作成で定義されています。最も高いレベルの演算子(つまり、演算子が最も低い優先順位を持つ式)はOrExpr
で、3.6 論理式で定義されています。
[1] | XPath |
::= | ExprSequence? |
[3] | Expr |
::= | OrExpr |
原始式(Primary expressions) は言語の基本となる部分です。これには、リテラル、変数、関数呼び出し、演算子の優先順位を制御するための丸括弧の使用などが含まれます。
[28] | PrimaryExpr |
::= | Literal | FunctionCall | ("$" VarName)
| ParenthesizedExpr |
[167] | VarName |
::= | QName |
リテラル(literal)は原子値の直接のシンタックスの表現です。XPathは2つの種類のリテラル、すなわち文字リテラル(string literal)と数値リテラル(numeric literal)をサポートしています。
[45] | Literal |
::= | NumericLiteral | StringLiteral |
[44] | NumericLiteral |
::= | IntegerLiteral | DecimalLiteral | DoubleLiteral |
[147] | IntegerLiteral |
::= | Digits |
[148] | DecimalLiteral |
::= | ("." Digits) | (Digits "."
[0-9]*) |
[149] | DoubleLiteral |
::= | (("." Digits) | (Digits
("." [0-9]*)?)) ("e" | "E") ("+" | "-")? Digits |
[162] | StringLiteral |
::= | ('"' (('"' '"') | [^"])* '"') | ("'" (("'"
"'") | [^'])* "'") |
文字リテラル(string literal)は原始型がxs:string
であって、値が区切りのクォーテーション・マークの間の文字によって表示される文字であるようなシングルトン・シーケンスです。もし、リテラルがシングル・クォーテーションで区切られている場合、リテラル内の2つの隣り合ったシングル・クォート文字は1つのシングル・クォート文字と解釈されます。同様に、もしリテラルがダブル・クォーテーションによって区切られている場合、リテラル内の2つの隣り合ったダブル・クォート文字は1つのクォート文字であると解釈されます。
もし、文字リテラルが属性の値の中で使用される場合、リテラルを区切るために使用されるクォート文字は属性を区切るために使用されるクォート文字と異なる必要があります。
".
"を含まず、e
やE
文字を含まない数値リテラル(numeric literal)の値は、型がxs:integer
で、値がxs:integer
データ型の規則に従って数値リテラルをパースすることにより得られる値であるような要素を含むシングルトン・シーケンスです。".
"を含むが、e
やE
文字を含まない数値リテラルの値は、原始型がxs:decimal
であり、値がxs:decimal
データ型の規則にしたがって数値リテラルをパースすることによって得られる値であるような要素を含むシングルトン・シーケンスです。e
やE
文字を含む数値リテラルの値は、原始型がxs:double
であり、値がxs:double
データ型の規則に従って数値リテラルをパースすることによって得られる値であるような要素を含むシングルトン・シーケンスです。
ここにリテラル式の例を示します。
"12.5"
は文字'1'、'2'、'5'を含む文字列を表します。
12
は整数値12を表します。
12.5は
十進数値の12と0.5を表します。
125E2は
倍精度浮動小数点値12500を表します。
ブーリアン値true
とfalse
は、それぞれ組み込み関数xf:true()
とxf:false()
に対する呼び出しにより表されます。
その他のXML Schemaの組み込み型の値は、その型に対するコンストラクタを呼び出すことにより生成することができます。XML Schemaの組み込み型に対するコンストラクタは[XQuery 1.0 and XPath 2.0 Functions and Operators]で定義されています。一般的に、ある型に対するコンストラクタ関数の名前は(ネームスペースを含めて)その型の名前と同じです。例えば、
xs:integer("12")
は整数値12を返します。
xs:date("2001-08-25")
は型がxs:date
で値が2001年8月25日を表す要素を返します。
xf:dayTimeDuration("PT5H")
は型がxf:dayTimeDuration
で値が5時間を表す要素を返します。
cast
式を使用してさまざまな型の値を生成することも可能です。例えば、
cast as hatsize(9)
は原始値が整数の9で、型がユーザー定義型でxs:integer
から派生したhatsize
という型の要素を返します。
変数(variable)は評価コンテキストにおいてその名前が結び付けれた値に対して評価します。結び付けられていない(unbound)変数を含む式は静的エラーとなります。変数はfor式(for expression)内の句と量化式(quantified expression)内の句により結び付けられます。
XPathではホスト言語環境において変数が結び付けられることも可能です。.
[46] | ParenthesizedExpr |
::= | "(" ExprSequence? ")" |
丸括弧は複数の演算子を含む式においてある特定の評価順序を守るために使用することができます。例えば、式(2 + 4) * 5
は30となります。丸括弧式(2 + 4)
が最初に評価され、その結果が5倍されるためです。丸括弧なしでは式2 + 4 * 5
は22となります。乗算演算子は加算演算子よりも高い優先順位を持つためです。
空の丸括弧は、3.3.1 シーケンスの作成に記述されているように、空シーケンスを表すために使用されます。
関数呼び出し(function call)はQNameと、それに続く丸括弧で囲まれたゼロまたはそれ以上の式から構成され、その式は引数(arguments)と呼ばれます。QNameと引数の数は静的コンテキストの中のスコープ内関数の名前とarity(パラメータの数)に一致しなくてはなりません。(2.1 式のコンテキスト参照。)それ以外の場合、静的エラーが発生します。
[47] | FunctionCall |
::= | <QName "("> (Expr ("," Expr)*)?
")" |
関数呼び出し式は以下のように評価されます。
各引数式が評価され、引数値が生成されます。
各引数値が対応する関数のパラメータの宣言された型に変換されます。このとき、以下に挙げた関数変換規則が使用されます。
関数が変換された引数の値を使用して実行されます。結果は関数の宣言された結果の型の値です。
関数変換規則(function conversion rules)は引数の値を必須型、つまり関数のパラメータの宣言された型、に変換するために使用されます。必須型はシーケンス型(Sequence Type)として表されます。関数変換規則は以下の通りです。
必須型が原子型である場合:
原子化(Atomization)が値に適用されます。もし、結果の原子値がxs:anySimpleType
型であると、その型を必須型にキャストしようとします。もし、キャストが失敗すると、関数呼び出しは動的型エラーを発生します。もし、原子値がB.1 Type Promotionのプロモーション規則を使用して必須型にプロモートできるような型を持つ場合、そのプロモーションが実行されます。
必須型がシーケンスあるいは原子型が任意に出現するような場合:
もし、値がノードを含む場合、これらのノードはその型付き値によって置き換えられます。各要素は原子値に対する変換規則を使用して必須原子型に変換されます。
必須型がその他のシーケンス型である場合、あるいは必須型が宣言されていない場合:
変換は実行されません。
もし、静的タイピング・フィーチャー(Static Typing Feature)が実装されており、(変換された)関数の引数または結果の静的型が、[XQuery 1.0 Formal Semantics]の中の静的型推測規則によって推測されるように、必須型のサブタイプでない場合は、静的エラーが発生します。もし、静的タイピング・フィーチャーが実装されてなく、(変換された)関数の引数あるいは結果の動的型が、シーケンス型マッチング(Sequence Type Matching)に対する規則に従うと必須型に一致しない場合、動的エラーが発生します。
関数のコア・ライブラリは[XQuery 1.0 and XPath 2.0 Functions and Operators]に定義されています。このライブラリの中の関数はデフォルトの関数のネームスペースを関数ライブラリのネームスペースに対して割り当てることで、ネームスペース接頭辞なしに呼び出すことができます。
XPath内のコンマ演算子(comma operator)は2つの目的を持っています。関数呼び出しないの引数を分離し、シーケンスを構成する式内の要素を分離します。(3.3.1 シーケンスの作成参照) これらの2つの使用を区別するために、関数呼び出しの個々の引数の境界に丸括弧を使用することができます。ここにいくつかの関数呼び出しの例を挙げます。
three-argument-function(1, 2, 3)
は3つの引数をもつ関数を表します。
two-argument-function((1, 2), 3)
は2つの引数を持つ関数を表します。最初の引数は2つの値のシーケンスです。
two-argument-function(1, ())
は2つの引数を持つ関数を表します。2つめの引数は空シーケンスです。
one-argument-function((1, 2, 3))
は1つの引数を持つ関数を表します。その引数は3つの値のシーケンスです。
one-argument-function(( ))
は1つの引数を持つ関数を表します。その引数は空シーケンスです。
zero-argument-function( )
は引数を持たない関数を表します。
XPathのコメントは情報を提供する注釈として使用することができます。このコメントは語彙的な構成要素であり、式の処理には影響を及ぼしません。
[59] | ExprComment |
::= | "{--" [^}]* "--}" |
コメントは式の中の主要なトークンの前や後に使用することができます。コメントが認識される正確な字句状況についてはA.1 Lexical structureを参照してください。
次はコメントの例です。
{-- Houston, we have a problem --}
編集者注: 上のEBNF記法では、"}"ではなく"--}"を禁止するべきです。
パス式(path expression)は、ツリー内のノードの位置を示すために使用されます。XPathの文法は演算子の優先順位で構成されるので、PathExprのシンタックスもPrimaryExprを含みます。一般的な使用方法として、パス式(path expression)という用語は単なるPrimaryExprではないPathExprを示します。
[18] | PathExpr |
::= | ("/" RelativePathExpr?) | ("//" RelativePathExpr) | RelativePathExpr |
[19] | RelativePathExpr |
::= | StepExpr (("/" | "//") StepExpr)* |
パス式は1つ以上のステップから構成され、"/
"によって分離され、オプションとして"/
"や"//
"で始まります。最初の"/
"や"//
"は暗黙的にパス式の最初に付け加えられる1つ以上の最初のステップの短縮形で、以下に記述されています。
単一のステップから構成されるパス式は3.2.1 ステップに記述されているように評価されます。
2つ以上のステップで構成されるパス式は、//
が出現すると3.2.4 短縮シンタックスに記述されているように展開され、ステップのシーケンスが/
で分離されるようにします。その後、このステップのシーケンスは左側から右側に向けて評価されます。E1/E2
の各演算は以下のように評価されます。式E1
が評価され、結果がノードのシーケンスではない場合、動的エラーが発生します。結果のノードのシーケンスはドキュメント順に並び替えられ、ノード識別子に基づいて重複が除去されます。E1
の評価から得られる各ノードは、今度は、2.1.2 評価コンテキストに記述されているように、E2
の評価のための内部フォーカス(inner focus)を提供することになります。E2
の各評価は結果としてノードのシーケンスとなる必要があります。そうでない場合、動的エラーが発生します。全てのE2
の評価の結果として得られたノードのシーケンスが併せられ、ノード識別子に基づいて重複が除去され、結果がドキュメント順に並び替えられます。
パス式の1つの例として、child::div1/child::para
はコンテキスト・ノードの子であるdiv1
要素の子であるpara
要素を選択します。あるいは、言い換えるとコンテキスト・ノードの孫要素であり、親としてdiv1
要素を持つpara
要素を選択します。
パス式の最初の"/
"は、初期ステップxf:root(self::node())
の短縮形です。この初期ステップの結果は、コンテキスト・ノードを含むルート・ノードから始めることです。コンテキスト要素がノードではない場合、動的エラーが発生します。
パス式の最初の"//
"は初期ステップxf:root(self::node())/descendant-or-self:node()
の短縮形です。この初期ステップの結果は、コンテキスト・ノードと同じ階層を持つ全てのノードを含む初期ノード・シーケンスを作ることです。このノード・シーケンスはパス式内の続いて起こるステップにより取捨選択されることになります。もしコンテキスト要素がノードではない場合、動的エラーが発生します。
ステップ(step)は要素のシーケンスを生成し、それらは0以上の述語(predicates)により取捨選択されます。ステップの値は述語を満たす要素で構成されます。述語については3.2.2 述語に記述されています。
ステップは、原始式(primary expression)(3.1 原始式に記述されています)、あるいはフォワード・ステップ(forward step)、あるいはリバース・ステップ(reverse step)で構成されます。フォワード・ステップやリバース・ステップは常にノードのシーケンスを返します。フォワード・ステップやリバース・ステップは、コンテキスト・ノードから始まり、指定された軸(axis)によってコンテキスト・ノードから到達できるノードまで通っていくもの、と考えることができます。これらのステップには2つの部分があります。一つは軸で、これはステップが"動く方向"を定義します。もう一つがノード・テスト(node test)で、ステップにより選択されるノードの種類や名前を指定します。
ステップの短縮シンタックスでは、軸は省略することができ、その他の使用可能な短縮記法については3.2.4 短縮シンタックスに記述されています。
フォワード・ステップやリバース・ステップの短縮されていないシンタックスは、軸の名前とダブル・コロンにより分離されているノード・テストで構成されます。ステップの結果は、コンテキスト・ノードから指定された軸により到達可能なノードで、ノード・テストにより指定されたノードの種類や名前を持つノードで構成されます。例えば、ステップchild::para
はコンテキスト・ノードの子であるpara
要素を選択します。child
は軸の名前で、para
はこの軸上で選択される要素ノードの名前です。使用可能な軸については、3.2.1.1 軸に記述されています。使用可能なノード・テストに関しては、3.2.1.2 ノード・テストに記述されています。ステップの例については、3.2.3 非短縮シンタックスや3.2.4 短縮シンタックスで提供されています。
[29] | ForwardAxis |
::= | <"child" "::"> |
[30] | ReverseAxis |
::= | <"parent" "::"> |
XPathはドキュメントをトラバースするための軸(axes)を定義しています。しかし、ホスト言語はこの軸のサブセットを定義しても構いません。以下の軸が定義されています。
child
軸はコンテキスト・ノードの子です。
descendant
軸はコンテキスト・ノードの子孫です。子孫とは、子あるいは子の子、などです。このようにdescendant
軸は属性やネームスペース・ノードを含みません。
parent
軸はコンテキスト・ノードの親(存在すれば)です。
ancestor
軸はコンテキスト・ノードの祖先です。コンテキスト・ノードの祖先とは、コンテキスト・ノードの親、親の親、などで構成されます。このように、ancestor
軸はコンテキスト・ノードがルート・ノードでない限り、常にルート・ノードを含みます。
following-sibling
軸はコンテキスト・ノードの後ろにある兄弟ノードです。もし、コンテキスト・ノードが属性ノードやネームスペース・ノードである場合、following-sibling
軸はemptyです。
preceding-sibling
軸はコンテキスト・ノードの前にある兄弟ノードです。もし、コンテキスト・ノードが属性ノードやネームスペース・ノードである場合、preceding-sibling
軸はemptyです。
following
軸はコンテキスト・ノードと同じドキュメントやドキュメント・フラグメントに存在する全てのノードのうち、ドキュメント順でコンテキスト・ノードの後にあるもので、子孫と属性ノードとネームスペース・ノードを除外したものです。
preceding
軸はコンテキスト・ノードと同じドキュメントやドキュメント・フラグメントに存在する全てのノードのうち、ドキュメント順でコンテキスト・ノードの前にあるもので、祖先と属性ノードとネームスペース・ノードを除外したものです。
attribute
軸はコンテキスト・ノードの属性です。コンテキスト・ノードが要素でない限り、軸はemptyとなります。
namespace
軸はコンテキスト・ノードのネームスペース・ノードです。コンテキスト・ノードが要素でない限り、軸はemptyとなります。
self
軸はコンテキスト・ノード自身です。
descendant-or-self
軸はコンテキストノードとコンテキスト・ノードの子孫です。
ancestor-or-self
軸はコンテキスト・ノードとコンテキスト・ノードの祖先です。このように、ancestor-or-self
軸は常にルート・ノードを含みます。
軸はフォワード軸(forward axes)とリバース軸(reverse axes)に分けることができます。コンテキスト・ノード、あるいはドキュメント順でコンテキストノードより後のノードのみを含む軸はフォワード軸です。コンテキスト・ノード、あるいはドキュメント順でコンテキスト・ノードより前のノードを含む字句はリバース軸です。
XPathでは、parent
、ancestor
、ancestor-or-self
、preceding
、preceding-sibling
はリバース軸です。その他の全ての軸はフォワード軸です。ancestor
、descendant
、following
、preceding
、self
軸は、(属性ノードとネームスペース・ノードを無視すると)ドキュメントを分割します。これらは重複することはなく、全てを併せるとドキュメント内の全ノードが含まれます。
ステップにより選択されたノードのシーケンスでは、ノードのコンテキスト位置は軸に依存した方法で決定されます。もし軸がフォワード軸であった場合、コンテキスト位置はドキュメント順に割り当てられます。もし、軸がリバース軸であった場合、コンテキスト位置はドキュメント順の逆順に割り当てられます。どちらの場合も、最初のコンテキスト位置は1です。
ノード・テスト(node test)はステップにより選択されるノードが真となる必要がある条件です。条件はノードの種類(要素、属性、テキスト、ドキュメント、コメント、処理命令、ネームスペース)を基にする、あるいはノードの名前を基にします。
[31] | NodeTest |
::= | KindTest | NameTest |
[32] | NameTest |
::= | QName | Wildcard |
[33] | Wildcard |
::= | "*" | <NCName ":"
"*"> | <"*" ":" NCName> |
[34] | KindTest |
::= | ProcessingInstructionTest |
[35] | ProcessingInstructionTest |
::= | <"processing-instruction" "("> StringLiteral? ")" |
[36] | CommentTest |
::= | <"comment" "("> ")" |
[37] | TextTest |
::= | <"text" "("> ")" |
[38] | AnyKindTest |
::= | <"node" "("> ")" |
各軸は主ノード種類(principal node kind)を持ちます。もし、軸が要素を含む場合、主ノード種類は要素です。それ以外の場合、軸が含むノードの種類になります。したがって、
QNameであるノード・テストは、そのノードの種類(kind)が主ノード種類で、そのノードの展開名(expanded-name)がQNameで示される展開名に等しい場合のみ真となります。例えば、child::para
はコンテキスト・ノードの子であるpara
要素を選択します。もし、コンテキスト・ノードがpara
という子要素を持たない場合、空のノードのセットを選択することになります。attribute::abc:href
はコンテキスト・ノードの属性で、QNameがabc:href
である属性を選択します。コンテキスト・ノードがそのような属性を持たない場合、空のノードのセットを選択することになります。
ノード・テスト内のQNameはその式のコンテキストのスコープ内ネームスペースを使用して展開名に展開されます。名前テストとして使用される接頭辞を持たないQNameは、その式のコンテキストのデフォルトの要素ネームスペースに関連付けられたネームスペースURIを持ちます。もし、QNameがスコープ内ネームスペースと合わない接頭辞を持つ場合、静的エラーとなります。
ノード・テスト*
はどんな主ノード種類のノードに対しても真となります。例えば、child::*
はコンテキスト・ノードの全ての子要素を選択します。attribute::*
はコンテキスト・ノードの全ての属性を選択します。
ノード・テストはNCName:*
の形となることもあります。この場合、接頭辞はQNameと同じ方法で、コンテキスト・ネームスペース宣言を使用して展開されます。もし、式のコンテキストに接頭辞に対するネームスペース宣言がない場合には、静的エラーとなります。名前のローカル部分に関わらず、その展開名が接頭辞が展開するネームスペースURIを持つような主ノード種類の全てのノードに対して、ノード・テストは真となります。
ノード・テストは*:NCName
の形となることもあります。この場合、ノード・テストはネームスペースに関わらず、ローカル名がそのNCNameと一致するような主ノード種類の全てのノードに対して真となります。
ノード・テストtext()
は任意のテキスト・ノードに対して真となります。例えば、child::text()
はコンテキスト・ノードの子であるテキスト・ノードを選択します。同様に、ノード・テストcomment()
は任意のコメント・ノードに対して真となり、ノード・テストprocessing-instruction()
は任意の処理命令に対して真となります。processing-instruction()テ
ストは文字リテラル(String Literal)の引数を取ることができます。この場合、ターゲット・アプリケーションがこの文字リテラルの値に等しい場合に真となります。
ノード・テストnode()
はどんなノードに対しても真となります。
注:
XMLのQNameと整合性を保つため、ワイルドカード使用時には空白文字は許されません。例えば、"prefix:*"は許されますが、"prefix : *"は許されません。
[43] | Predicates |
::= | ("[" Expr "]")* |
述語は述語式(predicate expression)と呼ばれる式で構成され、角括弧で囲まれます。述語はシーケンスを取捨選択するために使用され、ある要素を残し、他の要素を除外します。取捨選択されるシーケンスの各要素に対して、2.1.2 評価コンテキストに記述されているように、その要素から得られる内部フォーカス(inner focus)を使用して述語式が評価されます。述語式の結果は、以下に示すように述語真偽値(predicate truth value)と呼ばれるブーリアン値になります。述語真偽値がtrue
である要素は残され、述語真偽値がfalse
である値は除外されます。
述語真偽値は以下の規則を順番に適用することにより得られます。
もし、述語式の値が空シーケンスであった場合、述語真偽値はfalse
となります。
もし、述語式の値が数値型の原子値であった場合、述語真偽値は述語式の値がコンテキスト位置と等しい場合にのみtrue
となります。
もし、述語式の値がブーリアン型の原子値であった場合、述語真偽値は述語式の値と等しくなります。
もし、述語式の値が少なくとも一つのノードを含むシーケンスである場合、述語真偽値はtrue
となります。この場合の述語真偽値はノードの内容に依存しません。
それ以外の場合、型例外が発生します。
ここで、述語を含むステップの例を挙げます。
この例はコンテキスト・ノードの子である2番目の"chapter"要素を選択します。
child::chapter[2]
descendant::toy[attribute::color = "red"]
この例は、コンテキスト・ノードの子要素である"employee"要素のうち、"secretary"サブ要素を持つ要素を選択します。
child::employee[secretary]
述語はフォワード・ステップやリバース・ステップではない原始式(primary expression)でも使用できます。以下に例を示します。
1から100の整数値のうち、5で割ることができるものを全てリストします。(to
演算子に関しては、3.3.1 シーケンスの作成を参照してください。)
(1 to 100)[. mod 5 eq 0]
このセクションでは、各ステップにおいて軸が明示的に示されているパス式の例を示します。これらの例で示されているシンタックスは非短縮シンタックス(unabbreviated syntax)と呼ばれます。多くの一般的な場合において、3.2.4 短縮シンタックスに説明されているように、短縮シンタックス(abbreviated syntax)を使用してより簡潔にパス式を記述することが可能です。
child::para
はコンテキスト・ノードの子のpara
要素を選択します。
child::*
はコンテキスト・ノードのすべての子要素を選択します。
child::text()
はコンテキスト・ノードの子であるテキスト・ノードを選択します。
child::node()
はコンテキスト・ノードの全ての子を、ノード型が何であろうと、選択します。
attribute::name
はコンテキスト・ノードのname
という属性を選択します。
attribute::*
はコンテキスト・ノードの全ての属性を選択します。
descendant::para
はコンテキスト・ノードの子孫のpara
要素を選択します。
ancestor::div
はコンテキスト・ノードの先祖の全てのdiv
要素を選択します。
ancestor-or-self::div
はコンテキスト・ノードの先祖の全てのdiv
要素を選択し、もしコンテキスト・ノードがdiv
要素であれば、コンテキスト・ノードも選択します。
descendant-or-self::para
はコンテキスト・ノードの子孫のpara
要素を選択し、もしコンテキスト・ノードがpara
要素であれば、コンテキスト・ノードも選択します。
self::para
は、もしコンテキスト・ノードがpara
要素であれば、コンテキスト・ノードを選択し、それ以外であれば、何も選択しません。
child::chapter/descendant::para
はコンテキスト・ノードの子であるchapter
要素の子孫であるpara
要素を選択します。
child::*/child::para
はコンテキスト・ノードの孫である全てのpara
要素を選択します。
/
はコンテキスト・ノードを含むノード階層のルートを選択します。
/descendant::para
はコンテキスト・ノードと同じドキュメント内の全てのpara
要素を選択します。
/descendant::list/child::member
はコンテキスト・ノードと同じドキュメント内にあり、親list
を持つ全てのmember
要素を選択します。
child::para[xf:position() = 1]
はコンテキスト・ノードの子の最初のpara
要素を選択します。
child::para[xf:position() = xf:last()]
はコンテキスト・ノードの子の最後のpara
要素を選択します。
child::para[xf:position() = xf:last()-1]
はコンテキスト・ノードの子の最後から一つ手前のpara
要素を選択します。
child::para[xf:position() > 1]
はコンテキスト・ノードの子のpara
要素のうち、最初のpara
要素以外の全てのpara
要素を選択します。
following-sibling::chapter[xf:position() = 1]
はコンテキスト・ノードの次の兄弟であるchapter
要素を選択します。
preceding-sibling::chapter[xf:position() = 1]
はコンテキスト・ノードの前の兄弟であるchapter
要素を選択します。
/descendant::figure[xf:position() = 42]
はドキュメント内の42番目のfigure
要素を選択します。
/child::doc/child::chapter[xf:position() =
5]/child::section[xf:position() = 2]
はドキュメント要素doc
の5番目のchapter
要素の2番目のsection
要素を選択します。
child::para[attribute::type="warning"]
はコンテキスト・ノードの子のpara
要素のうち、type
という属性がwarning
という値を持つ全てのものを選択します。
child::para[attribute::type='warning'][xf:position() =
5]
はコンテキスト・ノードの子のtype
属性がwarning
という値を持つ5番目のpara
要素を選択します。
child::para[xf:position() =
5][attribute::type="warning"]
はコンテキスト・ノードの子の5番目のpara
要素が、もしtype
属性がwarning
という値を持つ場合に、選択します。
child::chapter[child::title='Introduction']
はコンテキスト・ノードの子の、Introduction
という値を持つtitle
子要素を1つ以上持つchapter
要素を選択します。
child::chapter[child::title]
はコンテキスト・ノードの子の、title
子要素を1つ以上もつchapter
要素を選択します。
child::*[self::chapter or self::appendix]
はコンテキスト・ノードの子の、chapter
要素とappendix
要素を選択します。
child::*[self::chapter or self::appendix][xf:position() =
xf:last()]
はコンテキスト・ノードの子の、最後のchapter
要素あるいはappendix
要素を選択します。
[41] | AbbreviatedForwardStep |
::= | "." | ("@" NameTest)
| NodeTest |
[42] | AbbreviatedReverseStep |
::= | ".." |
短縮シンタックスは以下の短縮形を許します。
元も重要な短縮は、child::
がステップから除外することができるという点です。実際、child
はデフォルトの軸です。例えば、パス式section/para
はchild::section/child::para
の短縮形です。
属性にも短縮形があります。attribute::
は@
に短縮されます。例えば、パス式para[@type="warning"]
はchild::para[attribute::type="warning"]
の短縮形であるため、type
属性がwarning
と等しい値を持つpara
子要素を選択します。
//
は/descendant-or-self::node()/
の短縮形です。例えば、//para
は/descendant-or-self::node()/child::para
の短縮形であるため、ドキュメント内の任意のpara
要素を選択します。(ドキュメント要素であるpara
要素も//para
によって選択されます。ドキュメントノードはルート・ノードの子であるためです。)div1//para
はdiv1/descendant-or-self::node()/child::para
の短縮形であるため、子要素div1
の子孫の全てのpara
要素を選択します。
パス式//para[1]
は/descendant::para[1]
と同じ意味ではないことに注意してください。後者は子孫の最初のpara
要素を選択するのに対して、前者は子孫のpara
要素のうち、自分の親に対して最初のpara
子要素であるような、全ての要素を選択します。
.
で構成されるステップはコンテキスト要素を返します。これは、特に//
と合わせて使用すると有用です。例えば、パス式.//para
はコンテキスト・ノードの全てのpara
子孫要素を返します。
..
で構成されるステップはparent::node()
の短縮形です。例えば、../title
はparent::node()/child::title
の短縮形であるため、コンテキスト・ノードの親のtitle
子要素を選択します。
短縮シンタックスを使用したパス式の例を挙げます。
para
はコンテキスト・ノードの子のpara
要素を選択します。
*
はコンテキスト・ノードの全ての子要素を選択します。
text()
はコンテキスト・ノードの全てのテキスト・ノードを選択します。
@name
はコンテキスト・ノードのname
属性を選択します。
@*
はコンテキスト・ノードの全ての属性を選択します。
para[1]
はコンテキスト・ノードの最初の子para
を選択します。
para[xf:last()]
はコンテキスト・ノードの最後の子para
を選択します。
*/para
はコンテキスト・ノードの全ての孫para
を選択します。
/doc/chapter[5]/section[2]
はdoc
の5番目のchapter
の2番目のsection
を選択します。
chapter//para
はコンテキスト・ノードの子要素chapter
の子孫のpara
要素を選択します。
//para
はドキュメント・ルートの子孫の全てのpara
要素を選択します。つまり、コンテキスト・ノードと同じドキュメント内の全てのpara
要素を選択します。
//list/member
はコンテキストノードと同じドキュメント内のlist
という親を持つ全てのmember
要素を選択します。
.
はコンテキスト・ノードを選択します。
.//para
はコンテキスト・ノードの子孫のpara
要素を選択します。
..
はコンテキスト・ノードの親を選択します。
../@lang
はコンテキスト・ノードの親のlang
属性を選択します。
para[@type="warning"]
はコンテキスト・ノードの子のtype
属性がwarning
という値を持つ全てのpara
要素を選択します。
para[@type="warning"][5]
はコンテキスト・ノードの子のtype
属性がwarning
という値を持つ5番目のpara
要素を選択します。
para[5][@type="warning"]
はコンテキスト・ノードの子の5番目のpara
要素が、type
属性がwarning
という値を持つ場合に、それを選択します。
chapter[title="Introduction"]
はコンテキスト・ノードの子の、Introduction
に等しい文字列値を持つtitle
要素を1つ以上持つchapter
要素を選択します。
chapter[title]
はコンテキスト・ノードの子の、title
という子を1つ以上持つchapter
要素を選択します。
employee[@secretary and @assistant]
はコンテキスト・ノードの子の、secretary
属性とassistant
属性を持つemployee
要素を全て選択します。
book/(chapter|appendix)/section
は、chapter
またはappendix
という親を持つsection
要素のうち、そのchapter
またはappendixが、
コンテキスト・ノードの子であるbook
要素の子であるようなものを選択します。
book/xf:id(publisher)/name
はxf:id(book/publisher)/name
と同じ結果を返します。
XPathはシーケンスを作り、結合するための演算子をサポートしています。シーケンス(sequence)はゼロ以上の要素の順番を持つ集まりです。要素(item)は原子値かノードです。要素はその要素を含む長さ1のシーケンスと同一です。シーケンスはネストすることはありません。例えば、値1、(2, 3)、( ) を結合して一つのシーケンスにすると、結果は(1, 2, 3) というシーケンスとなります。
[2] | ExprSequence |
::= | Expr ("," Expr)* |
[11] | RangeExpr |
::= | AdditiveExpr ( "to" AdditiveExpr )* |
シーケンスを作成する一つの方法は、コンマ演算子(comma operator)を使用することです。これは、各被演算子を評価し、その結果の値を順番に結合して、一つのシーケンスを作成します。
ExprSequenceは本来式ではなく、一般的に式が予期されるところで使用される場合には、丸括弧で囲まれなくてはなりません。空の丸括弧は空シーケンスを表すために使用することができます。
シーケンスは重複した値やノードを含む可能性がありますが、シーケンスは他のシーケンスの要素になることはありません。2つ以上の入力シーケンスを結合して新しいシーケンスが作成されるとき、その新しいシーケンスは入力シーケンスの全ての要素を含み、その長さは入力シーケンスの長さの合計となります。
シーケンスを構成する式の例を示します。
子の式は5つの整数のシーケンスです。
(10, 1, 2, 3, 4)
この式は、10, (1, 2)、空シーケンス ( )、(3, 4) というシーケンスから1つのシーケンスを作成します。
(10, (1, 2), (), (3, 4))
これは、評価されて以下のシーケンスとなります。
10, 1, 2, 3, 4
この式はコンテキスト・ノードの全てのsalary
子要素と、それに続くbonus
子要素となります。
(salary, bonus)
$price
は10.50
という値に結び付けられているとすると、次の式
($price, $price)
は評価されて次のシーケンスとなります。
10.50, 10.50
RangeExprは連続する整数のシーケンスを作成するために使用することができます。to
演算子は2つの被演算子を取ります。両方とも必須型はintegerです。シーケンスは、2つの整数の被演算子とその2つの被演算子の間の全ての整数を含むものが作成されます。最初の日演算子が2つ目の小さい場合はシーケンスは昇順となり、そうでない場合には降順となります。
この例は範囲式(range expression)を1つの被演算子として使用し、シーケンスを作成しています。
(10, 1 to 4)
これは評価されて次のようなシーケンスとなります。
10, 1, 2, 3, 4
この例は長さ1のシーケンスを作成します。
10 to 10
これは評価されて単一の整数10
を含むシーケンスとなります。
[14] | UnionExpr |
::= | IntersectExceptExpr ( ("union"
| "|") IntersectExceptExpr )* |
[15] | IntersectExceptExpr |
::= | UnaryExpr ( ("intersect"
| "except") UnaryExpr )* |
XPathでは、ノードのシーケンスを結合するいくつかの演算子を提供しています。union
演算子と|
演算子は等価です。これらは被演算子として2つのノード・シーケンスを取り、いずれかの被演算子に出現するノードを全て含むシーケンスを返します。intersect
演算子は2つのノード・シーケンスを被演算子として取り、両方の被演算子に出現する要素を全て含むシーケンスを返します。except
演算子は2つのノード・シーケンスを被演算子として取り、最初の被演算子に出現し、2つ目の被演算子に出現しないノードを全て含むシーケンスを返します。これらの演算子は全てノード識別子を基に重複なくドキュメント順に結果のシーケンスを返します。union
、intersect
、except
の被演算子がノードではない要素を含む場合、動的エラーが発生します。
シーケンスを結合する式の例をいくつか示します。A、B、Cという名前の3つの要素ノードを仮定します。$seq1
はAとBを含むシーケンスに結び付けられ、$seq2
もAとBを含むシーケンスに結び付けられ、$seq3
はBとCを含むシーケンスに結び付けられていると仮定します。このとき、
$seq1 union $seq1
を評価するとAとBを含むシーケンスとなります。
$seq2 union $seq3
を評価するとAとBとCを含むシーケンスとなります。
$seq1 intersect $seq1
を評価するとAとBを含むシーケンスとなります。
$seq2 intersect $seq3
を評価するとBのみを含むシーケンスとなります。
$seq1 except $seq2
を評価すると空シーケンスとなります。
$seq2 except $seq3
を評価するとAのみを含むシーケンスとなります。
ここに述べられているシーケンス演算子に加えて、[XQuery 1.0 and XPath 2.0 Functions and Operators]には要素に索引アクセスをするための関数、シーケンスのサブシーケンスのための関数、索引によりシーケンスに要素を挿入したり削除したりする関数、シーケンスから重複した値やノードを削除する関数などが含まれています。
XPathは加算、減算、乗算、除算、余剰の計算のための、通常の2項および単項の算術演算子を提供しています。
[12] | AdditiveExpr |
::= | MultiplicativeExpr ( ("+"
| "-") MultiplicativeExpr )* |
[13] | MultiplicativeExpr |
::= | UnionExpr ( ("*" | "div"
| "idiv" | "mod") UnionExpr )* |
[16] | UnaryExpr |
::= | ("-" | "+")* ValueExpr |
[17] | ValueExpr |
::= | ValidateExpr | CastExpr
| PathExpr |
2項の減算演算子は、もし前のトークンの一部と解釈されてしまうような場合には、空白文字を先に置かなくてはなりません。例えば、a-b
は名前として解釈されますが、a - b
は算術演算として解釈されます。
算術式は以下の規則をエラーが発生するか値が計算されるまで順番に適用することで評価されます。
原子化(Atomization) が各被演算子に適用され、各被演算子は結果として単一の原子値か空シーケンスとなります。
もし、いずれかの被演算子が空シーケンスであった場合、演算の結果は空シーケンスとなります。
もし、被演算子がxs:anySimpleType
の型を持つ場合、xs:double
にキャストされます。キャストが失敗すると、動的エラーが発生します。
もし、2つの被演算子が異なる型を持っており、これらの型がB.1 Type Promotionのプロモーション規則を使用して共通の型にプロモートできる場合、被演算子は両方とも最も低い共通の方にプロモートされます。例えば、もし最初の被演算子がxs:decimal
から派生したhatsize
という型で、2番目の被演算子がxs:integer
から派生したshoesize
という型であるとすると、両方の被演算子はxs:decimal
にプロモートされます。
もし、被演算子の型が演算子に対して妥当である場合、演算子が被演算子に対して適用され、結果として原子値か動的エラー(例えば、0による除算によるエラー)となります。算術演算子が受け入れることができる原子型と、その結果の型の組み合わせは、B.2 Operator Mappingに一覧されています。もし、被演算子の型が演算子に対して妥当ではない場合、型例外が発生します。
XPathはdiv
とidiv
という名前の2つの除算演算子をサポートしています。div
演算子は任意の数値型の被演算子を受け入れます。div
演算子の結果はそれらの被演算子の最も低い共通の型となります。しかし、もし両方の被演算子がxs:integer
である場合、はxs:double
の型の結果を返します。一方、idiv
演算子では被演算子はxs:integer
の型である必要があり、結果はxs:integer
の型で、端数は切り捨てられます。
算術式の例を示します。
以下の最初の式は-1.5E0
を返し、2番目の式は-1
を返します。
-3 div 2 -3 idiv 2
2つのdate値の減算の結果はxf:dayTimeDuration
型の値となります。
$emp/hiredate - $emp/birthdate
この例は減算演算子とハイフンの違いを示しています。
$unit-price - $unit-discount
単項演算子は2項演算子よりも高い優先順位を持っており、当然丸括弧の使用に従います。
-($bellcost + $whistlecost)
比較式(comparison expression)は、2つの値を比較することができます。XPathは4種類の比較式を提供しており、それらは値比較(value comparison)、一般比較(general comparison)、ノード比較(node comparison)、順序比較(order comparisom)と呼ばれます。
[10] | ComparisonExpr |
::= | RangeExpr ( (ValueComp |
[25] | ValueComp |
::= | "eq" | "ne" | "lt" | "le"
| "gt" | "ge" |
[24] | GeneralComp |
::= | "=" | "!=" | "<" | "<="
| ">" | ">=" |
[26] | NodeComp |
::= | "is" | "isnot" |
[27] | OrderComp |
::= | "<<" | ">>" |
XPath式がXMLドキュメント内に記述されるとき、特殊文字に対するXMLのエスケープ規則に従わなくてはなりません。つまり、"<
"は"<
"と書かなくてはなりません。
値比較(value comparisom)は単一の値を比較することを意図しています。値比較の結果は以下の規則を順番に適用することで定義されます。
原子化(Atomization) が各被演算子に適用され、結果としてそれぞれの被演算子に対する単一の原子値、または空シーケンスが得られます。
もし、どちらかの被演算子が空シーケンスである場合には、結果は空シーケンスとなります。
もし、どちらかの演算子がxs:anySimpleType
型を持つ場合、その被演算子は必須型にキャストされますが、どのようにキャストされるかは以下に従います。
もし、他方の被演算子が数値である場合には、必須型はxs:double
です。
もし、他方の被演算子がxs:anySimpleType
である場合には、必須型はxs:string
です。
それ以外では、必須型は他方の被演算子の型です。
もし、キャストが失敗すると、動的エラーが発生します。
もし、値比較が異なる数値型の被演算子に対して行われる場合、B.1 Type Promotionのプロモーション規則に従って、一方の被演算子が他方の被演算子の型にプロモートされます。例えば、xs:integer
型の値はxs:decimal
にプロモートされ、xs:decimal
型の値はxs:double
にプロモートされます。
比較の結果は、最初の被演算子の値が2番目の被演算子の値に対して(等しい、等しくない、より小さい、以下である、より大きい、以上である)場合にtrue
となります。それ以外の場合には比較の結果はfalse
となります。B.2 Operator Mappingにはどの原子型の組み合わせが互換性があり、さまざまな型の値に対してどのように比較が実行されるのかが記述されています。最初の被演算子の値が2番目の被演算子の値と互換性がない場合、型例外が発生します。
値比較の例を示します。
以下の比較は、$book1
が単一のauthor
サブ要素を持ち、その値が"Kennedy"である場合のみ真となります。
$book1/author eq "Kennedy"
編集者注: 現時点での値比較演算子の定義は他動詞ではありません。ワーキング・グループでは、値比較から暗黙的なキャストを除いて、それらを一般比較に付け加えることで、値比較を他動詞とする議論がなされています。
一般比較(general comparisons)は値比較に存在に関するセマンティックスを付け加えて定義されています。一般比較の被演算子は任意の長さのシーケンスとなります。一般比較の結果は常にtrue
またはfalse
です。
シーケンスA
とB
に対する一般比較A = B
は、もしA
の要素a
とB
の要素b
に対して値比較a eq b
がtrue
である場合に、true
となります。それ以外の場合には、A = B
はfalse
となります。
同様に、
A != B
は、A
の中のa
とB
の中のb
に対して、a ne b
がtrue
であるときのみ、true
となります。
A < B
は、A
の中のa
とB
の中のb
に対して、a lt b
がtrue
であるときのみ、true
となります。
A <= B
は、A
の中のa
とB
の中のb
に対して、a le b
がtrue
であるときのみ、true
となります。
A > B
は、A
の中のa
とB
の中のb
に対して、a gt b
がtrue
であるときのみ、true
となります。
A >= B
は、A
の中のa
とB
の中のb
に対して、a ge b
がtrue
であるときのみ、true
となります。
一般比較の例を示します。
以下の比較は、$book1
のauthor
サブ要素が"Kennedy"である場合に、真となります。
$book1/author = "Kennedy"
ノード比較(node comparison)の結果は以下の規則を順番に適用することで定義されます。
各被演算子は単一のノードか空シーケンスのいずれかでなくてはなりません。それ以外の場合、動的エラーが発生します。
もし、どちらかの被演算子が空シーケンスである場合、比較の結果は空シーケンスとなります。
is
演算子を使用した比較は、2つの被演算子が同じ識別子を持つノードである場合にtrue
となります。それ以外の場合は、false
となります。isnot
演算子を使用した比較は、2つの被演算子が異なる識別子を持つノードである場合はtrue
となります。それ以外はfalse
となります。ノードの識別子に関する議論については、[XQuery 1.0 and XPath 2.0 Data Model]を参照してください。
is
演算子の使用例を示します。
以下の比較は、左側と右側がそれぞれ全く同じ単一のノードに評価されるときのみ、真となります。
//book[isbn="1558604820"] is //book[call="QA76.9 C3845"]
順序比較の結果は、以下の規則を順番に適用することで定義されます。
両方の被演算子は単一ノード、あるいは空シーケンスでなくてはなりません。その他の場合には動的エラーが発生します。
もし、どちらかの被演算子が空シーケンスであった場合、比較の結果は空シーケンスとなります。
<<
演算子による比較は、最初の被演算子ノードが2番目の被演算子ノードよりもドキュメント順で前にある場合true
にとなります。それ以外では、false
となります。
>>
演算子による比較は、最初の被演算子ノードが2番目の被演算子ノードよりもドキュメント順で後にある場合true
にとなります。それ以外では、false
となります。
順序比較の例を示します。
以下の比較は、左側で識別されるノードが右側で識別されるノードのドキュメント順で前に出現する場合に真となります。
//purchase[parcel="28-451"] << //sale[parcel="33-870"]
論理式(logical expression)はand式(and-expression)あるいはor式(or-expression)のどちらかです。もし、論理式でエラーが発生しない場合、その値は常にブーリアン値true
またはfalse
です。
[4] | OrExpr |
::= | AndExpr ( "or" AndExpr )* |
[5] | AndExpr |
::= | ForExpr ( "and" ForExpr )* |
論理式を評価する最初のステップは、その各被演算子の有効ブーリアン値(effective boolean value)を見つけることです。(2.4.3.2 有効ブーリアン値参照)
and式の値はその被演算子の有効ブーリアン値(EBV's)によって決定されます。もし、有効ブーリアン値の計算の間にエラーが発生した場合は、以下の表に示すようにand式は動的エラーを発生させることができます。
AND: | EBV2 = true | EBV2 = false | error in EBV2 |
EBV1 = true | true | false | error |
EBV1 = false | false | false | false or error |
error in EBV1 | error | false or error | error |
or式の値はその被演算子の有効ブーリアン値(EBV's)によって決定されます。もし、有効ブーリアン値の計算の間にエラーが発生した場合は、以下の表に示すようにor式は動的エラーを発生させることができます。
OR: | EBV2 = true | EBV2 = false | error in EBV2 |
EBV1 = true | true | true | true or error |
EBV1 = false | true | false | error |
error in EBV1 | true or error | error | error |
論理式の被演算子が評価される順番は実装に依存します。上記の表は、or式は最初の式が真と評価されたらtrue
を返すことができ、最初の式がエラーであったらエラーを発生させることができるという考え方で定義されています。同様に、and式は最初の式が偽と評価されたらfalse
を返すことができ、最初の式がエラーであったらエラーを発生させることができます。これらの規則の結果として、論理式は、以下に例を示すように、エラーの存在によりdeterministicではありません。
論理式の例を示します。
以下の式はtrue
を返します。
1 eq 1 and 2 eq 2
1 eq 1 or 2 eq 3
以下の式はfalse
を返すか、動的エラーを発生させるかのどちらかです。
1 eq 2 and 3 idiv 0 = 1
以下の式はtrue
を返すか、動的エラーを発生させるかのどちらかです。
1 eq 1 or 3 idiv 0 = 1
以下の式は動的エラーを発生させなくてはいけません。
1 eq 1 and 3 idiv 0 = 1
and式とor式に加えて、XPathはnot
という名前の一般的なシーケンスをパラメータとして取り、ブーリアン値を返す関数を提供します。not
関数はパラメータを有効ブーリアン値に減らします。その後、もしパラメータの有効ブーリアン値がfalse
であったらtrue
を返し、パラメータの有効ブーリアン値がtrue
であったらfalse
を返します。被演算子の有効ブーリアン値を見つける間にエラーが発生した場合には、not
関数は動的エラーを発生させます。not
関数は[XQuery 1.0 and XPath 2.0 Functions and Operators]に記述されています。
XPathでは、繰り返しのためにFor式(For expression)が提供されます。この種類の式は2つ以上のドキュメントの結合を計算したり、データを再構築したりする際に有用なことが多くあります。
[6] | ForExpr |
::= | (ForClause "return")* QuantifiedExpr |
[21] | ForClause |
::= | <"for" "$"> VarName
"in" Expr
("," "$" VarName "in" Expr)* |
For式の節は以下のように解釈されます。
for
節は式の1つ以上の変数と関連付けられており、式が評価された値のシーケンスからなるカルテシアン積から得られる変数バインディングの組を作ります。変数バインディングの組は以下に記述されているように順序を持つシーケンスとして生成されます。
return
節はFor式の結果を作るために使用される式です。return
節はfor
節によって生成された全ての組に対して一度だけ実行されます。return
節内の式は、各実行のたびに一度評価され、For式の結果はこれらの実行結果を含む順序を持つシーケンスとなります。
変数名はそれがバインドされる前には使用されませんし、バインドされる式の中でも使用されません。for
節の中でバインドされる変数は、それがバインドされるFor式の終わりまでスコープ内にあります。もし変数名が現在のスコープで既にバインドされている場合には、変数名はその変数がスコープの外に行くまでは新しくひバインドされた変数を参照します。スコープ外に行った時点で変数名は再び以前にバインドされていた変数を参照します。
for
節が複数式である場合、変数バインディングの組は式によって返されるシーケンスのカルテシアン積から得られます。組の順序は、左から右へ、シーケンスが形成された順番によって決まります。
以下の式はfor
節内の式のカルテシアン積からどのように組が生成されるかを示したものです。
for $i in (1, 2), $j in (3, 4) return ($i, $j)
上の式の結果は以下の通りです。(順番が重要です。)結果は数値のシーケンスとして表されていることに注意してください。
(1, 3, 1, 4, 2, 3, 2, 4)
以下の例は参考文献文書を評価して、各著者のファーストネームとラストネームと、それに続いてその著者の本のタイトルを含むシーケンスを作成しています。例は以下の入力に基づいています。
<bib> <book> <title>TCP/IP Illustrated</title> <author> W. Stevens </author> <publisher>Addison-Wesley</publisher> </book> <book> <title>Advanced Programming in the Unix environment</title> <author> W. Stevens </author> <publisher>Addison-Wesley</publisher> </book> </bib>
著者リストは著者の一覧で、各author要素は著者の名前とその著者が書いた本の一覧です。ある著者が1冊以上の本を書いた場合、その著者の名前は参考文献内で1回以上出現します。しかし、各著者名は著者リスト内では1回のみ出現させたいと考えます。distinct-values
関数により重複を除くことができます。
distinct-values
関数は入力としてノードのシーケンスを取り、値の重複が取り除かれたシーケンスを返します。このシーケンスの順番は重要ではありません。2つの要素は、その名前と属性と正規化された内容が等しい場合に、重複値を持つと考えられます。
以下の式が入力の参考文献を変換して著者リストにするために使用されます。
for $a in distinct-values(//author) return ($a, for $b in //book[author = $a] return $b/title)
上記の式の結果は以下の要素のシーケンスを生成します。
<author>W. Stevens</author>, <title>TCP/IP Illustrated</title>, <title>Advanced Programming in the Unix environment</title>
注
照会を記述する場合は、For式とパス式を組み合わせるときは注意が必要です。パス式は常にドキュメント順に結果を返すのに対し、For式の結果の順番はfor
節内のシーケンスの順番によって決定されるということを覚えておくことは重要です。
XPathはif
、then
、else
というキーワードに基づく条件式(conditional expression)をサポートしています。
[8] | IfExpr |
::= | (<"if" "("> Expr ")"
"then" Expr "else")* InstanceofExpr |
if
キーワードに続く式はテスト式(test expression)と呼ばれ、then
とelse
キーワードに続く式は、それぞれthen式(then-expression)、else式(else-expression)と呼ばれます。
条件式を処理する最初のステップは、2.4.3.2 有効ブーリアン値に定義されているように、テスト式の有効ブーリアン値(effective boolean value)を見つけることです。
条件式の値は以下のように定義されます。もし、テスト式の有効ブーリアン値がtrue
であれば、then式の値が返されます。もし、テスト式の有効ブーリアン値がfalse
であれば、else式の値が返されます。
条件式には動的エラーを伝える特別の規則があります。もし、テスト式の有効ブーリアン値がtrue
であれば、条件式はelse式で発生するどんな動的エラーも無視します。(発生させません。)この場合、else式には返される結果がないため、評価する必要がありません。同様に、もしテスト式の有効ブーリアン値がfalse
であった場合、条件式はthen式で起こる動的エラーは無視され、then式は評価される必要はありません。
条件式の例を示します。
この例では、テスト式は比較式です。
if ($widget1/unit-cost < $widget2/unit-cost) then $widget1 else $widget2
この例では、テスト式はdiscounted
という名前の属性の存在をテストしており、その値には依存していません。
if ($part/@discounted) then $part/wholesale else $part/retail
量化式(quantified expression)は存在に関する普遍的な量化をサポートします。量化式の値は常にtrue
またはfalse
です。
[7] | QuantifiedExpr |
::= | ((<"some" "$"> | <"every" "$">) VarName
"in" Expr
("," "$" VarName "in" Expr)*
"satisfies")* IfExpr |
量化式(quantified expression)は数量詞(quantifier)、つまりsome
やevery
などのキーワードで始まり、変数をバインドするための1つ以上のin節(in-clause)が続き、キーワードsatisfies
とテスト式が続きます。各in節は値のシーケンスを返す式により変数に関連付けられます。For式のfor節の場合のように、in節ではバインディングの式が返すシーケンスのカルテシアン積から得られる値を使用して、変数バインディングの組を生成します。概念的には、テスト式がそれぞれの変数バインディングの組に対して評価されます。2.4.3.2 有効ブーリアン値で定義されているように、結果はテスト式の有効ブーリアン値に依存します。量化式の値は以下の規則に従って定義されます。
数量詞がsome
である場合には、量化式はテスト式の評価の少なくとも一つが有効ブーリアン値true
を持てばtrue
となります。そうでなければ、量化式はfalse
となります。この規則は、もしin節が0個のバインディングの組を生成した場合、量化式の値はfalse
であることを意味しています。
数量詞がevery
である場合、量化式はテスト式の評価の全てが有効ブーリアン値true
を持てばtrue
となります。そうでなければ、量化式はfalse
となります。この規則は、もしin節が0個のバインディングの組を生成した場合、量化式の値はtrue
となることを意味しています。
テスト式がさまざまなバインディングの組に対して評価する順序は実装に依存します。数量詞がsome
である場合、実装は1つのバインディングの組のテスト式が有効ブーリアン値true
を持つことがわかったら直ちにtrue
を返し、バインディングの組のテスト式がエラーとなった場合直ちに動的エラーを発生することができます。同様に、数量詞がevery
である場合、1つのバインディングの組のテスト式が有効ブーリアン値false
を持つことがわかったら、直ちにfalse
を返し、バインディングのテスト式がエラーとなった場合直ちに動的エラーを発生させることができます。この規則の結果として、量化式の値は以下に示す例のように、エラーの存在によりdeterministicではありません。
量化式の例を示します。
この式は全てのpart
要素がdiscounted
属性を持つ場合(これらの値に関わらず)true
となります。
every $part in //part satisfies $part/@discounted
この式は少なくとも1つのemployee
要素が比較式を満たせばtrue
となります。
some $emp in //employee satisfies ($emp/bonus > 0.25 * $emp/salary)
以下の例では、各量化式は(1, 2, 3)
と(2, 3, 4)
のシーケンスのカルテシアン積から形成される9組の変数バインディングに対するテスト式を評価します。some
で始まる式はtrue
となりますが、every
で始まる式はfalse
となります。
some $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4
every $x in (1, 2, 3), $y in (2, 3, 4) satisfies $x + $y = 4
量化式はtrue
を返すか、動的エラーを発生します。テスト式が1つの変数バインディングに対してはtrue
を返しますが、別のものに対してはエラーが発生するからです。
some $x in (1, 2, "cat") satisfies $x * 2 = 4
量化式はfalse
を返すか、動的エラーを発生します。テスト式が1つの変数バインディングに対してはfalse
を返しますが、別のものに対してはエラーが発生するからです。
every $x in (1, 2, "cat") satisfies $x * 2 = 4
関数パラメータ内で使用されるのに加えて、シーケンス型はinstance of
式、cast
式、treat
式で明示的に発生します。
[9] | InstanceofExpr |
::= | ComparisonExpr ( <"instance" "of"> SequenceType )? |
ブーリアン演算子instance of
は、シーケンス型マッチング(Sequence Type Matching)の規則に従って、最初の被演算子の値が2番目の被演算子内の型の名前と一致するとtrue
を返します。それ以外はfalse
を返します。例えば、
5 instance of xs:integer
この例は値が指定した型のインスタンスであるので、true
を返します。
. instance of element
この例はコンテキスト要素は要素ノードであるので、true
を返します。
[23] | CastExpr |
::= | (<"cast" "as"> | <"treat" "as">) SequenceType ParenthesizedExpr |
時々、ある値を特定のデータ型に変換する必要がある場合があります。この目的のために、XPathは既存の値に基づいて特定の型の新しい値を生成するcast
式を提供します。cast
式は被演算子として、入力式とターゲット型(target type)と呼ばれるシーケンス型の2つを取ります。cast
式は最初に入力式に関して原子化(atomization)を行い、その結果は単一の原子入力値、あるいは空シーケンスとなります。もし入力値が空シーケンスであった場合、cast
式は空シーケンスを返します。そうでない場合、cast
式は入力値と同じ字句表現を持つターゲット型の新しいインスタンスを作成します。入力値の型は入力型(input type)と呼ばれます。cast
は、以下に示すように入力型とターゲット型の特定の組み合わせのみサポートしています。これらの規則のために、次の意味でサブタイプ(subtype)とスーパータイプ(supertype)という用語を使用します。もし、型Bが型Aから派生した場合、BはAのサブタイプであり、AはBのスーパータイプです。
cast
は[XQuery 1.0 and XPath 2.0 Functions and Operators]に一覧となっている入力型とターゲット型の組み合わせをサポートします。これらの組み合わせのそれぞれに対して、入力型とターゲット型は両方とも組み込みのスキーマ型です。例えば、xs:string
の型の値はxs:decimal
にキャストすることができます。
[XML Schema]で定義されている全ての組み込み型Tに対して、名前がTと同じでそのセマンティックスがTをターゲット型としたcast式と同じであるような、コンストラクタ関数が提供されます。例えば、関数呼び出しxs:decimal($stringvalue)
は式cast as xs:decimal($stringvalue)
と等価です。もし、コンストラクタ関数の引数がリテラルである場合、関数の結果は静的に計算され、この処理中にエラーが発生すると静的エラーとして報告されます。コンストラクタ関数は[XQuery 1.0 and XPath 2.0 Functions and Operators]により詳細に記述されています。
cast
は入力型が原子型から派生しており、ターゲット型が入力型のスーパータイプである場合にサポートされます。例えば、shoesize
がxs:integer
から制限により派生した場合、型shoesize
の値はxs:integer
型にキャストすることができます。
cast
はターゲット型が原子型から派生し、入力型がxs:string
、xs:anySimpleType
、ターゲット型のスーパータイプである場合にサポートされます。もし、入力型がxs:string
またはxs:anySimpleType
である場合、その文字列値はターゲット型の字句空間(lexical space)に存在しなくてはならず、ターゲット型に対するスキーマ定義規則を使用してターゲット型に変換されます。もし、入力型がターゲット型のスーパータイプであった場合、その値はターゲット型の値空間(value
space)に変化なくマップされ、ターゲット型の全てのファセットに対して一致することを確認されます。("pattern"ファセットの確認は入力値の標準字句表現(canonical
lexical representation)を生成する必要がある可能性があります。)
上に挙げられていない入力型とターゲット型の任意の組み合わせに対して、cast
式は静的エラーを発生します。
入力値をターゲット型の値空間にキャストすることができない場合、動的エラーが発生します。これは、いずれかのターゲット型のファセットが満たされない時の場合も含みます。例えば、cast as xs:integer($x)
は、もし$x
の型がxs:decimal
で、値が4.99
である場合には動的エラーを発生します。この値はzero fractional digitsでは表現することができないためです。
cast
に加えて、XPathはtreat
と呼ばれる型チェック式を提供しています。これは、式とシーケンス型の2つの被演算子を取ります。しかし、cast
と異なり、treat
はその被演算子の型や値を変えることはありません。その代わり、treat
の目的は実行時に式が予期している型であるかを確認することを目的としています。
treat as type1 (expr2)
のセマンティックは以下の通りです。
静的分析の間(もし静的タイピング・フィーチャーが実装されていれば)
type1
は[XQuery 1.0 Formal Semantics]のサブタイプの定義を使用して、expr2
の静的型のサブタイプでなくてはなりません。そうでない場合、静的型エラーが発生します。treat
式の静的型はtype1
です。これにより、type1
のパラメータを必要とする関数の引数として式を使用することができます。
式の評価の間(実行時)
2.4.2 シーケンス型のシーケンス型マッチングの規則を使用して、もしexpr2
がtype1
に一致すれば、treat
式はexpr2
の値を返します。そうでない場合、動的エラーが発生します。もし、expr2
の値が返る場合、その識別子は保存されます。treat
式は式の被演算子の値は実行時の予期している方に位置することを確認しています。
例:
treat as element of type USAddress ($myaddress)
$myaddress
の静的型はelement of type Address
で、element of type USAddress
よりも特定されていない型です。しかし、実行時に$myaddress
の値は、シーケンス型マッチングの規則を使用して、element of type USAddress
に一致しなくてはなりません。そうでない場合、動的エラーが発生します。
[22] | ValidateExpr |
::= | "validate" SchemaContext? "{" Expr
"}" |
編集者注: このシンタックスのかぎ括弧はXSLTに埋め込まれた場合に、問題になる可能性があります。問題267参照
バリデート式(validate expression)はその引数をスコープ内スキーマ定義に関して、[XML Schema]に記述されているスキーマ妥当性検証処理を使用して、引数の妥当性を検証します。バリデート式の引数は要素のシーケンスです。妥当性検査により、要素や属性ノードはそれぞれの識別子を持つ新しいノードで置き換え、それは型注釈と妥当性検査処理により作成されるデフォルト値を含みます。もし、ノード階層がバリデート式で妥当性が検証された場合、これらのノードの階層関係は妥当性検証処理によって作成されるノード間でも保持されます。
ローカルで宣言される要素や属性を妥当性検査するために、スキーマ・コンテキストがオプションとして指定されます。もし、コンテキストが指定されない場合には、妥当性検証される資料内の全ての上位レベルの名前がグローバル名として扱われます。
以下の例は変数にバインドされている値を妥当性検査します。
バリデート式は、[XML Schema]Part1の3.11.4 で定義されているように、同一性制約が適用されないということを除いて、完全なスキーマ妥当性検査処理を実行します。単純型の全てのファセットがチェックされ、XML Schemaの規格で定義されているようにデフォルト値が提供されます。
式の妥当性検査は以下のステップと等価です。
式の値がデータ・モデルからXML Information Set ([XML Infoset]参照)に変換されます。このステップは式の値をXMLの形式にシリアライズして、パースしてInformation Set を作成する処理と等価です。
前のステップで作成されたInformation Set は、[XML Schema]の規則に従って、スコープ内スキーマ定義を使用して妥当性検査されます。このステップの結果はスキーマ妥当性検証済みインフォセット(PSVI)です。もし、妥当性検査ステップが成功しない場合、動的エラーが発生します。
前のステップのPSVIは、[XQuery 1.0 and XPath 2.0 Data Model]で記述されているマッピングにより、データ・モデルに再度変換されます。
バリデート式はローカルに定義されている要素や属性の妥当性を検査する際に使用されるスキーマ・コンテキストを含むことが可能です。スキーマ・コンテキストが提供されると、全ての要素のQNameは、XMLドキュメント内のそのコンテキストに存在する場合のQNameとして解釈されます。スキーマ・コンテキストがQNameで始まっていると、そのQNameはグローバルに宣言されている要素の名前であると解釈されます。しかし、スキーマ・コンテキストがtype
キーワードで始まっている場合、最初のQNameはグローバルに宣言されている型の名前であると解釈されます。スキーマ・コンテキスト内のステップは、以下の例で示されるように、グローバルに宣言されている要素や型に対する相対的なパスを辿ります。これは、[XML Schema], Part 0で定義されているスキーマを基にしています。
$x
がshipTo
要素にバインドされていると仮定します。validate in po:purchaseOrder {$x}
は、変数$x
をグローバルな要素宣言po:purchaseOrder
のコンテキスト内で妥当性検査します。
$y
がproductName
要素にバインドされていると仮定します。validate in po:purchaseOrder/items/item {$y}
は、変数$y
をグローバル要素宣言po:purchaseOrder
の中のitems
要素の中のitem
要素のコンテキスト内で妥当性検証します。
$z
がzip
要素にバインドされていると仮定します。validate in type po:USAddress {$z}
は、変数$z
の値をグローバルな型宣言po:USAddress
のコンテキスト内で妥当性検査します。