XPath の基礎 (3) です。

//div[@name='hoge']

上記のように書けば、name 属性が “hoge” であるすべての div タグを選択できます。

実は XPath には様々な省略記法があり、実は上記もその省略記法で書かれていて、省略しないで書くと以下のようになります。

/descendant-or-self::node()/child::div[attribute::name='hoge']

省略記法で書かれたものに比べると、省略記法を使用しないものは長ったらしくなっていますが、XPath の構成要素をちゃんと理解することは、XPath を書くときの一助になってくれると思います。

XPath の主要な構成要素には、ノードテスト述部 があります。

軸は、選択するもののベースを決めるもので、child、self、parent、attribute などがあります。

child であれば子ノード、self であれば自ノード、parent であれば親ノード、attribute であれば属性を意味します。

なお軸の後ろには :: をつける決まりです。

ノードテスト

ノードテストは、指定した軸の何を選択するかを決めるもので、要素名や属性名 や text()、 * などがあります。

例えば child::div であれば、子ノードのうちの div 要素を意味し、child::* であれば、子ノードのうちのすべての要素を意味します。

child::text() であれば、子テキストノードを意味します。CSS では意識することはありませんが、タグとタグの間にあるテキスト部分(<div>*ここ*</div>)がテキストノードです。

述部

述部は、軸とノードテストで指定したものをフィルタリングするものです。なくてもかまいません。

述部は [ と ] で表し、その中に **式** を指定します。ここでは簡単に、真か偽かを判定する式だと考えましょう。

例えば attribute::name=’hoge’ なら「属性 name が “hoge” である」という条件でフィルタリングすることになります。

ここで最初に戻って、以下の XPath について考えてみます。

/descendant-or-self::node()/child::div[attribute::name='hoge']

まず、最初の / は「文書のルート」です。これはそのように決められています。

descendant-or-self が軸で、その意味は「自分およびその子孫」になります。

node() はノードテストで、すべての子ノードを意味します。

したがって /descendant-or-self::node() は、「全部のノード」を意味することになります。

次に child::div[attribute::name=’hoge’] ですが、この child は軸で、/descendant-or-self::node() で選択されたそれぞれの子、ということになります。

child::div の div はノードテストで、要素 div をあらわしています。つまり、/descendant-or-self::node() で選択されたそれぞれの子の div 要素、平たく言えば 全部の div 要素 ということになります。

[attribute::name=’hoge’] は述部で、上記にある通り「name 属性が “hoge” である」という条件になります。ですから、すべての div 要素のうち、name 属性が “hoge” であるもの を選択するということになります。