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

関連ページ