XPathによる要素特定(class属性値が複数の場合)
例えばHTMLソース内に<div class="a">というdivタグがあるとする。
このdivタグを特定するxpathは//div[@class="a"]である。
では<div class="a">だけでなく<div class="a ba">や<div class="ba a">などがhtmlソース内に混在する場合、class属性に属性値"a"が含まれているdivタグを特定するxpathはどうなるか。
htmlで複数の属性値を指定するには、空白区切りで<div class="a ab abc">などと書く。
//div[contains(@class,"a")]だと、例えば<div class="ab">などがマッチしてしまうのでダメ。
//div[contains(@class,"a ")] (aの後ろに空白追加)だと、<div class="abc ab a">のパターンがマッチしない。
また、このxpathだと<div class="ba c">のように属性値に"a"が含まれない要素がマッチしてしまう。
答え
期待のxpathは//div[contains(concat(" ", @class, " "), " a ")]となる。@classと属性値"a"をそれぞれ空白ではさむ。このxpathで以下パターンのdiv要素を評価してみる。
| 要素 | xpathの@classを展開後 | マッチする? |
|---|---|---|
<div class="a ab abc"> | //div[contains(concat(" ", "a ab abc", " "), " a ")] | マッチする |
<div class="ab a abc"> | //div[contains(concat(" ", "ab a abc", " "), " a ")] | マッチする |
<div class="ab abc a"> | //div[contains(concat(" ", "ab abc a", " "), " a ")] | マッチする |
<div class="a"> | //div[contains(concat(" ", "a", " "), " a ")] | マッチする |
<div class="ab abc"> | //div[contains(concat(" ", "ab abc", " "), " a ")] | マッチしない |
属性値"a"を含む要素がマッチすることを理解できるだろう。
今回はclass属性をみたが、複数の属性値を空白区切りで指定するような属性であれば、同様にマッチさせることができる。 つまり、特定の属性(ex. class)に特定の値(ex. "a")を持つ要素(ex. div)を探すことができる。