HTML::Selector::XPath@0.16 は CSS における class セレクタと等価な XPath を出力しない

再現コード


class_with_lf.t

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() を使うよう変更している。