32.6. 式
結果の型
デフォルトでは、XPath 式は org.w3c.dom.NodeList
型の 1 つ以上の XML ノードのリストを返します。しかし、型コンバーターのメカニズムを使用して、結果を別の型に変換することができます。Java DSL では、xpath()
コマンドの第 2 引数に結果の型を指定することができます。たとえば、XPath 式の結果を String
として返すには次のようにします。
xpath("/person/name/text()", String.class)
XML DSL では、以下のように resultType
属性で結果の型を指定することができます。
<xpath resultType="java.lang.String">/person/name/text()</xpath>
ロケーションパスにおけるパターン
XPath ロケーションパスでは、以下のパターンを使用することができます。
/people/person
基本的なロケーションパスは、特定の要素の入れ子になったロケーションを指定します。つまり、前のロケーションパスは、次の XML フラグメントの中の person 要素と一致することになります。
<people> <person>...</person> </people>
この基本パターンは、複数のノードにマッチする可能性があることに注意してください。たとえば、
people
要素内にperson
要素が 1 つ以上ある場合などがこれに該当します。/name/text()
-
要素の内部のテキストにアクセスするだけであれば、ロケーションパスに
/text()
を追加します。それ以外の場合は、ノードには要素の開始タグと終了タグが含まれます (ノードを文字列に変換するときにこれらのタグが含まれます)。 /person/telephone/@isDayTime
AttributeName 属性の値を選択するには、構文
@AttributeName
を使用します。たとえば、以下の XML フラグメントに適用すると、前述のロケーションパスはtrue
を返します。<person> <telephone isDayTime="true">1234567890</telephone> </person>
*
-
指定したスコープ内のすべての要素に一致するワイルドカード。たとえば、
/people/person/\*
はperson
のすべての子要素にマッチします。 @*
-
一致した要素のすべての属性にマッチするワイルドカード。たとえば、
/person/name/@\*
は、すべての一致したname
要素のすべての属性にマッチします。 //
すべてのネストされたレベルのロケーションパスにマッチします。たとえば、
//name
パターンは、以下の XML フラグメントで強調表示されているname
要素にすべてマッチします。<invoice> <person> <name .../> </person> </invoice> <person> <name .../> </person> <name .../>
..
- 現在のコンテキストノードの親を選択します。現在のコンテキストノードはドキュメントルートであり、親を持たないので、Apache Camel XPath 言語では通常は有用ではありません。
node()
- 任意の種類のノードにマッチします。
text()
- テキストノードにマッチします。
comment()
- コメントノードにマッチします。
processing-instruction()
- 処理命令ノードにマッチします。
述語フィルター
[Predicate]
のように、角括弧内に述語を追加すると、ロケーションパスに一致するノードのセットをフィルタリングできます。たとえば、ロケーションパスに [N]
を追加すると、一致するノードのリストから Nth 番目のノードを選択することができます。以下の式は、最初にマッチする person
要素を選択します。
/people/person[1]
以下の式は、最後から 2 番目の person
要素を選択します。
/people/person[last()-1]
特定の属性値を持つ要素を選択するために、属性の値をテストすることができます。以下の式は、surname
属性が Strachan または Davies のいずれかである name
要素を選択します。
/person/name[@surname="Strachan" or @surname="Davies"]
述語式は、接続詞 and
、or
、not()
のいずれかを使用して組み合わせることができ、さらに比較式 =
、!=
、>
、>=
、<
、⇐
を使用して式を比較することができます (実際には、小なりの記号は <
エンティティーに置き換える必要があります)。述語フィルターで XPath 関数を使うこともできます。
軸
XML 文書の構造では、ルート要素に一連の子要素が含まれており、それらの子要素の中にはさらに子要素が含まれているものもあります。このように見てみると、child-of 関係によってネストされた要素間がリンクされている場合、XML 文書全体が ツリー構造になります。この要素ツリーの特定のノード (これを コンテキストノード と呼びます) を選択した場合、選択したノードに関連したツリーの異なる部分を参照することがあります。たとえば、コンテキストノードの子、コンテキストノードの親、またはコンテキストノードと同じ親を共有するすべてのノード (兄弟ノード) を参照する場合があります。
XPath 軸 を使用して、ノード一致のスコープを指定し、現在のコンテキストノードを起点として相対的にノードツリーの特定部分に検索を制限します。軸は、一致させたいノード名の接頭辞として、AxisType::MatchingNode
という構文を使用して添付されます。たとえば、以下のように child::
軸を使用して、現在のコンテキストノードの子を検索することができます。
/invoice/items/child::item
child::item
のコンテキストノードは、パス /invoice/items
で選択される items
要素です。child::
軸は、検索対象をコンテキストノード items
の子に制限し、child::item
は item
という名前の items
の子にマッチします。child::
軸はデフォルトの軸であるため、先ほどの例は以下のように書くこともできます。
/invoice/items/item
しかし、他の軸も複数あり (合計 13 個)、その一部はすでに省略形で見てきました。@
は attribute::
の略であり、//
は descendant-or-self::
の略です。軸の一覧は以下のとおりです (詳細は下記リファレンスを参照)。
-
ancestor
-
ancestor-or-self
-
attribute
-
child
-
descendant
-
descendant-or-self
-
following
-
following-sibling
-
namespace
-
parent
-
preceding
-
preceding-sibling
-
self
関数
XPath は、述語を評価する際に便利な標準関数の小さなセットを提供します。たとえば、ノードセットから最後にマッチするノードを選択するには、以下のようにノードセット内の最後のノードのインデックスを返す last() 関数を使用します。
/people/person[last()]
前述の例では、シーケンスの最後の person
要素が選択されています (文書順)。
XPath が提供するすべての関数の詳細については、以下のリファレンスを参照してください。
リファレンス
XPath 文法の詳細については、XML Path Language, Version 1.0 仕様を参照してください。