再現コード
class 属性の値における「空白文字」
class 属性の値は:
The attribute, if specified, must have a value that is a set of space-separated tokens representing the various classes that the element belongs to.
HTML Standard
とあるように、a set of space-separated tokens
と定義されている。
では a set of space-separated tokens
の定義を参照すると:
A set of space-separated tokens is a string containing zero or more words (known as tokens) separated by one or more space characters, where words consist of any string of one or more characters, none of which are space characters.
HTML Standard
とある。
space characters
について合意を持たないといけなさそう。
The space characters, for the purposes of this specification, are U+0020 SPACE, U+0009 CHARACTER TABULATION (tab), U+000A LINE FEED (LF), U+000C FORM FEED (FF), and U+000D CARRIAGE RETURN (CR).
HTML Standard
とある。つまり改行 (line feed, carriage return) は「空白文字」として定義されている。
HTML::Selector::XPath のバグ
class 属性の値の前後に空白 (U+0020 SPACE) を追加して contains()
関数でマッチするか試しているが、前述の通り class 属性の値は U+0020 以外の文字も空白文字として許容する。
たとえば改行 (U+000A LINE FEED) があった場合には contains()
関数は偽を返すので、CSS における class セレクタと等価ではない。
対策と修正
XPath には normalize-space()
関数がある。この関数は、連続する空白文字をひとつの空白 (U+0020) に置き換える。
この Pull Request では normalize-space()
を使うよう変更している。