XPath (XML Path Language) とは

XPath(XML Path Language)とは、XMLで記述されたデータの問い合わせ言語です。SQLのSELECTのように、条件を指定してXMLデータを取得することができます。この記事では、XPathの使い方をご紹介します。

XPathとは

XMLデータはツリーとしてモデル化でき、また、要素や属性などXMLデータを構成する各パーツは、ツリーを構成するノードとしてモデル化できます。XPathのデータモデルでは、XMLデータを以下の7種類のノードから構成されるツリーと考えます。

XMLの取得

次にXPathの書式を示します

軸::ノード[式]

キーワード 対象
ancestor 祖先
ancestor-or-self カレントノードと祖先
attribute 属性
child
descendant 子孫
descendant-or-self カレントノードと子孫
following カレントノードより後に出現するノード
following-sibling 兄弟(カレントノードより後ろ)
namespace 名前空間
parent
preceding-sibling 兄弟(カレントノードより前)
preceding カレントノードより前に出現するノード
self カレントノード

軸には簡略化した記述方法があります。次に軸を簡略化した文法の一覧を示します。

XPathの軸
簡略化した文法 正式な文法 意味
記述省略 child
@ attribute 属性
. self::node() カレントノード
.. parent::node()
/ /descendant-or-self::node()/ すべてのノード

軸を簡略化して記述する場合は、軸とノードの区切り記号である「::」は省略します。

child

たとえば次のXMLがあったとする。

<library>
  <book isbn="4101235058">
    <title>深夜特急1 香港・マカオ</title>
  </book>
</library>

カレントノードがlibraryだとすると、子要素(book)を取得するには、XPathで次のように記述する。

子要素
表記XPath
通常 child::book
簡略 book

attribute

子要素(book)の属性「isbn」を取得するには、XPathで次のように記述する。

子要素の属性
表記XPath
通常child::book/attribute::isbn
簡略book/@isbn

たとえば次のXMLがあったとする。

<html>
  <body>
    <h1>XPathとは</h1>
  </body>
</html>

カレントノードがhtmlだとすると、孫要素(h1)を取得するには、XPathで次のように記述する。

孫ノード
表記XPath
通常child::body/child::h1
簡略body/h1

ノード

XML 文章内で特定のノードの位置を指定するための式をロケーションパスと呼びます。ロケーションパスには、厳密かつ詳細に記述する書き方と、簡略に記述する書き方(省略シンタックス)の2種類があります。

省略シンタックスの主な構文(ロケーションステップ)を以下の表に示します。

XPathのノード
構文 意味
/ ルートノードを選択します
. コンテキストノード(現在位置のノード)を選択します。
.. コンテキストノードの親を選択します。
name 子要素nameまたは属性name(子要素と属性の区別は軸で指定)
* 指定したパスの直下の全ての子要素または属性(子要素と属性の区別は軸で指定)
text() 指定したパスの直下のテキストを選択します。指定形式:パス/text()
node() 指定したパスの直下のノードを選択します(属性ノードは含みません)。指定形式:パス/node()
//element ルートノードの子孫ノードから要素ノード element を全て選択します。つまり、同じ名前をもつノードすべてを指定する場合に使用します。

ロケーションステップを1個以上"/"で繋いだものがロケーションパスです。階層構造は、ノード名とノード名を"/"で区切って記述します。

ロケーションパスには、現在位置のノードを起点として指定する「相対ロケーションパス」と、ルートノードを起点として指定する「絶対ロケーションパス」の2種類があります。

軸::ノード で指定した条件をさらに細かく指定するために使用します。

ノードを限定するには node_name[2] のように番号を指定するか、 node_name[@attrib_name="value"] のように条件を指定します。条件指定はand ,orなどで複合できます。

コンテキストノードの1番目の子要素bookを選択する。

book[1]

条件式に関数を使うこともできます。次の例では、コンテキストノードの最後の子要素bookを選択します。

book[last()]

式には以下に示す演算子を使用することができます。

演算子
演算子 説明
= 等しい
eq 等しい
!= 等しくない
ne 等しくない
< 左の値が右の値より小さい
lt 左の値が右の値より小さい
> 左の値が右の値より大きい
gt 左の値が右の値より大きい
<= 左の値が右の値以下
le 左の値が右の値以下
>= 左の値が右の値以上
ge 左の値が右の値以上
+ 加算
- 減算
* 乗算
div 除算
idiv
mod 剰余
and 論理積
or 論理和
not 否定
is ノードが一致する
isnot ノードが一致しない
<< ノードの出現が早い
>> ノードの出現が遅い

コンテキストノードの子要素bookのうち、子要素authorを1個以上持つものを選択する。

book[author]

例: author属性とprice属性の両方をもつコンテキストノードの子要素bookを全て選択

child::book[attribute::author and attribute::price]
book[@author and @price]

=, eq

例: カレントノードの子 book の属性 isbn が 4-274-06453-0 と等しい

child::book[attribute::isbn='978-0241411193']
book[@isbn='978-0241411193']

例: コンテキストノードの子要素bookのうち、文字列値が "Charles Dickens" である子要素authorを1個以上持つものを選択

child::book[attribute::author eq "Charles Dickens"]
book[author eq "Charles Dickens"]

and

and演算子により「複数の条件をすべて満たす」という条件を設定できます。 例えば、「 /library/book/author/text() が“夏目漱石”で、なおかつ /library/book/publisher/text() が“岩波文庫”である」ノードを表すXPath表現式は次のようになります。

/library/book[author/text()="夏目漱石" and publisher/text()="岩波文庫"]

上記のXPATHで取得できるノードの例を以下に示す。

<book isbn="4003101111">
  <title>こころ</title>
  <author>夏目漱石</author>
  <publisher>岩波文庫</publisher>
</book>

or

or演算子により「複数の条件のどれかを満たす」という条件を設定できます。 例えば、「 /library/book/author/text() が“芥川龍之介”か、または“夏目漱石”である」ノードを表すXPath表現式は次のようになります。

/library/book[author/text()="芥川龍之介" or author/text()="夏目漱石"]

上記のXPATHで取得できるノードの例を以下に示す。

<book isbn="4101025037">
  <title>蜘蛛の糸・杜子春</title>
  <author>芥川龍之介</author>
  <publisher>新潮文庫</publisher>
</book>
<book isbn="4101025010">
  <title>羅生門・鼻</title>
  <author>芥川龍之介</author>
  <publisher>新潮文庫</publisher>
</book>
<book isbn="4003101111">
  <title>こころ</title>
  <author>夏目漱石</author>
  <publisher>岩波文庫</publisher>
</book>
<book isbn="9784041001202">
  <title>こころ</title>
  <author>夏目漱石</author>
  <publisher>角川文庫</publisher>
</book>

参考文献

World Wide Web Consortium (2010) XML Path Language (XPath) 2.0 (Second Edition)