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” であるもの を選択するということになります。