| Version 29 (modified by amachang, 4 years ago) |
|---|
XPath から CSS Selector への変換を真剣に検討するページ
XPath を IE8 で querySelector 出来るセレクタに変換する方法を考えよう」
HTML で使用することに特化していい
XPath から要素を取得する過程で使う目的
ブレスト
出来る系
//aaa//bbb//ccc
=> aaa bbb ccc
/aaa/bbb/ccc
=> html > bbb > ccc (ルートは html と決まっているから妥協)
id("hoge")
=> #hoge
id("hoge") | //aaa[@hoge="fuga"]
=> #hoge, aaa[hoge="fuga"]
//aaa/*[1]
=> aaa > *:first-child
//aaa[contains(@hoge, 'fuga')]
=> aaa[hoge*="fuga"]
//aaa[ends-with(@hoge, 'fuga')]
=> aaa[hoge$="fuga"]
(//aaa | //bbb)/ccc
=> aaa > ccc, bbb > ccc
//aaa[@hoge=1+1]
=> aaa[hoge="2"] (パース時に定数を計算しているので)
出来ない系
aaa/bbb/ccc => child 軸から始まる (一時的に id を付けてやるのはどうか、パフォーマンス気になる) ./aaa/bbb/ccc => self 軸 .. => parent 系の軸や兄要素にさかのぼる系 //aaa[.="hoge"] => 条件部に属性以外の条件 (ただし、条件部の結果にコンテキストの概念が必要ない場合は、実行時に変換できる) //aaa[@hoge=count(.//bbb//ccc)] => ネストしている (パース時に .//bbb//ccc をセレクタに直して実行し、 .//bbb//ccc の値が確定したら全体をセレクタに直して実行するのはどうか)
IE8 で対応するセレクタ
http://msdn.microsoft.com/en-us/library/cc351024%28VS.85%29.aspx
- Simple Selector
- .value
- #value
- E
- *
- [att=val]
- [att]
- [att|=val]
- [att~=val]
- [att^=val]
- [att*=val]
- [att$=val]
- Combinator
- E + F
- E > F
- E F
- E ~ F
方法を考える
走り書きで
方法 1
- XPath をパースする
- 定数に出来るところはする
- 構文木を変換できる部分木を探す
- 式を上から順に走査 (再帰 a)
- PathExpr? だった場合
- FilterExpr? を変換する
- id(Expr) の場合
- Expr を変換する
- 定数の場合
- "#hogehoge" を生成して次へ
- その他の場合
- null を返す
- 定数の場合
- id(Expr) が持つ Predicate を走査する
- 処理 c が CSS Selector を返す場合は
- ここまで連結してきた CSS Selector に、ここで返ってきた CSS Selector を連結して続ける
- その他の場合
- ここまでしか解析できていないという情報と、ここまで連結してきた CSS Selector を返す
- 処理 c が CSS Selector を返す場合は
- 続く NodeTest? を変換する
- 処理 b
- Expr を変換する
- context-node() (JavaScript?-XPath 独自の概念) の場合
- root-node() (JavaScript?-XPath 独自の概念) の場合
- id(Expr) の場合
- NodeTest? を変換する (処理 b)
- Predicate を変換する (処理 c)
- Predicate が定数で boolean 型, string 型の場合
- (パース時点で、消滅させるべきなので、ここに来たらエラーにする)
- Predicate が定数で boolean 型, string 型の場合
- これ以上変換できないので、
- Predicate が定数で boolean 型, string 型の場合
- FilterExpr? を変換する
- UnionExpr? がだった場合
- すべての PathExpr? が CSS Selector を返した場合で、その CSS Selector がカンマを含まない場合
- すべての CSS Selector をカンマでつないで返す
- そのほかの場合
- 何も返さない
- すべての PathExpr? が CSS Selector を返した場合で、その CSS Selector がカンマを含まない場合
- そのほかの場合
- 何も返さない
- PathExpr? だった場合
- 式を上から順に走査 (再帰 a)
- ---------------------------
- 上から順に変換する
- Step は以下の様に変換する
- (FIXME) Predicate も含め、すべて変換できる Step は
- (FIXME) 属性軸以外の軸で始まる LocationPath? がオペランドとして現れた場合、それを含む式は変換できない
- id 関数は以下の様に変換する
- UnionExpr? は以下のように変換する
- Step は以下の様に変換する
- 上から順に変換する
- 実行する
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)