@@ -5,21 +5,48 @@ Jsoup代码解读之七-实现一个CSS Selector
5
5
6
6
当当当!终于来到了Jsoup的特色:CSS Selector部分。selector也是[ webmagic] ( https://github.com/code4craft/webmagic ) 开发的一个重点。附上一张street fighter的图,希望以后webmagic也能挑战Jsoup!
7
7
8
- w3c的CSS Selector规范:[ http://www.w3.org/TR/CSS2/selector.html ] ( http://www.w3.org/TR/CSS2/selector.html )
9
-
10
8
Jsoup的select包里,类结构如下:
11
9
12
10
![ uml] [ 2 ]
13
11
14
- Jsoup的select核心是` Evaluator ` 。` Evaluator ` 是一个抽象类,它只有一个方法:
12
+ 在最开始介绍的Jsoup的时候,就已经说过` NodeVisitor ` 和` Selector ` 了。` Selector ` 是select部分的对外facade,而` NodeVisitor ` 则是遍历树的底层API,CSS Selector也是根据` NodeVisitor ` 实现的遍历。
13
+
14
+ Jsoup的select核心是` Evaluator ` 。Selector所传递的表达式,会经过` QueryParser ` ,最终编译成一个` Evaluator ` 。` Evaluator ` 是一个抽象类,它只有一个方法:
15
15
16
16
``` java
17
17
public abstract boolean matches(Element root, Element element);
18
18
```
19
19
20
- 注意这里传入了root,是为了某些情况下对树进行遍历时用的。在我们调用document.select(css)方法之后,Jsoup会将
20
+ 注意这里传入了root,是为了某些情况下对树进行遍历时用的。
21
+
22
+ Evaluator的设计简洁明了,所有的Selector表达式单词都会编译到对应的Evaluator。例如` #xx ` 对应` Id ` ,` .xx ` 对应` Class ` ,` [] ` 对应` Attribute ` 。这里补充一下w3c的CSS Selector规范:[ http://www.w3.org/TR/CSS2/selector.html ] ( http://www.w3.org/TR/CSS2/selector.html )
21
23
24
+ 当然,只靠这几个还不够,Jsoup还定义了` CombiningEvaluator ` (对Evaluator进行And/Or组合),` StructuralEvaluator ` (结合DOM树结构进行筛选)。
22
25
26
+ 这里我们可能最关心的是,“div ul li”这样的父子结构是如何实现的。这个的实现方式在` StructuralEvaluator.Parent ` 中,贴一下代码了:
27
+
28
+ ``` java
29
+ static class Parent extends StructuralEvaluator {
30
+ public Parent (Evaluator evaluator ) {
31
+ this . evaluator = evaluator;
32
+ }
33
+
34
+ public boolean matches (Element root , Element element ) {
35
+ if (root == element)
36
+ return false ;
37
+
38
+ Element parent = element. parent();
39
+ while (parent != root) {
40
+ if (evaluator. matches(root, parent))
41
+ return true ;
42
+ parent = parent. parent();
43
+ }
44
+ return false ;
45
+ }
46
+ }
47
+ ```
48
+
49
+ 这里Parent包含了一个` evaluator ` 属性,会根据这个evaluator去验证所有父节点。注意Parent是可以嵌套的,所以这个表达式"div ul li"最终会编译成` And(And(Parent(Tag("div")),Tag("ul")),Tag("li")) ` 这样的Evaluator组合。
23
50
24
51
[ 1 ] : http://static.oschina.net/uploads/space/2013/0830/180244_r1Vb_190591.jpg
25
52
0 commit comments