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)を探すことができる。