XPath | |
追記
コメントでFirefox以外からの利用もありうることに気がつきました。
そう考えると、normalize-space()は残しておいたほうがいいのかもしれません。
このentryは、AutoPagerizeとLDRFullFeedのWedataのデータからnormalize-spaceが削除されていることに気づいて書いたのですが、現在の時点で不具合が出ていないのかは少し気になります。
誤解のないように最初に。
要するにclassにnormalize-spaceはかける必要はないよって話です。
textとかにnormalize-spaceかけるのとはまた違います。
気になった理由は、ある日突然drryさんがnormalize-space(@class)を@classに変えていたのを見たからなのですが。
そもそもnormalize-space関数ってのはXPath内で使える関数です。
normalize-space 関数は文字列から前後の空白文字を取り除き、連続する空白文字を 1 つのスペースに置き換え、その結果として得られる文字列を返します。
ページが見つかりません | Mozilla Developer Network
原文も
The normalize-space function returns the argument string with whitespace normalized by stripping leading and trailing whitespace and replacing sequences of whitespace characters by a single space. Whitespace characters are the same as those allowed by the S production in XML. If the argument is omitted, it defaults to the context node converted to a string, in other words the string-value of the context node.
XML Path Language (XPath)
TAB文字を仮に\tとおくと、
" a ss \t \t b d "
のような文字列を渡すと、
"a ss b d"
にして返すわけです。
AutoPagerizeのSITEINFOとかでこんな書き方を見たことがあるのではないでしょうか。
ここでは、
<div class="page entry"></div>
を参照したいとします。
//div[contains(concat(" ",normalize-space(@class)," ")," page ")]
これのやってることをここで簡単に説明すると、
こんなにまどろっこしいことをする理由は、要するにclassが複数定義できるからです。また、前後にスペースを入れて、スペースごとmatchさせることで、たとえば
<div class="prevpage"></div>
なんてものを参照する危険を避けています。
で、本題なのですが、先ほどの2番、つまりnormalize-spaceのやってることっていうのは、FirefoxだとGeckoがやってくれるんですね。つまり描画された後のdiv要素は
<div class="page entry"></div>
にしといてくれるので、実質normalize-spaceは必要ないんです。ちゃんとTAB文字も変換しといてくれます。
ただし、全角スペースは変換してくれません。まあこれはもともとclassの区切りとしては認められていないものなので当然ですし、もちろんnormalize-spaceも半角スペースに変換してはくれません。
しかもありがたいことに描画したあとからJavaScriptなんかで
elm.className += " next";
なんかしても
<div class="page entry next"></div>
にしておいてくれるという優れもの。
normalize-spaceも一応関数なので、微細にですがXPath処理速度に影響します。よって今度からはpageクラスをもつdiv要素を厳密に参照するときのXPathは
//div[contains(concat(" ",@class," ")," page ")]
でいいようです。