Mercurial > paraspace
annotate paraspace/structpath.py @ 135:b488ca519709
Make sure elements are absolute incremental for sorted arrays when injecting.
- All sorted array of DEXFile must be absolute incremental.
- If injected one is the same order as one already in the array, the one
in array are used to replace injected one.
- All references to clone and injected one refer to ones already in array
instead.
author | Thinker K.F. Li <thinker@codemud.net> |
---|---|
date | Tue, 09 Aug 2011 21:28:13 +0800 |
parents | aa05cc7ccd0d |
children |
rev | line source |
---|---|
36
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
1 ## \brief A xpath liked query language |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
2 # |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
3 # Implement a xpath liked query language. |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
4 # |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
5 # Structpath uses syntax of Python for predicate. That means you must use |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
6 # '==' instead of '='. |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
7 # |
36
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
8 # You need to create a context before querying. |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
9 # \code |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
10 # ctx = parent_context(None) |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
11 # ctx.root = car() |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
12 # root = ctx.root |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
13 # |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
14 # root.wheels = [wheel(), wheel(), wheel(), wheel()] |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
15 # root.handle = handle() |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
16 # |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
17 # ctx.all_classes = {'car': car, 'wheel': wheel, 'handle': handle} |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
18 # ctx.class_instances = { |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
19 # 'car': [root], |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
20 # 'wheel': root.wheels, |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
21 # 'handle': [root.handle] |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
22 # } |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
23 # |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
24 # objs = find_objs_path(ctx, '/car/wheels') |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
25 # \endcode |
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
26 # |
38
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
27 import re |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
28 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
29 _reo_nest_chars = re.compile('[\'"\\[\\]/\\\\]') |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
30 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
31 class context(object): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
32 all_classes = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
33 class_instances = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
34 root = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
35 objs = None |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
36 |
36
0b9ac7cef6e5
Add documentation for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
35
diff
changeset
|
37 def __init__(self, objs=None, ctx=None): |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
38 if ctx: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
39 self.all_classes = ctx.all_classes |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
40 self.class_instances = ctx.class_instances |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
41 self.root = ctx.root |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
42 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
43 self.objs = objs |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
44 pass |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
45 |
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
46 def get_parent(self, obj): |
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
47 raise NotImplementedError, 'get_parent() is not implemented' |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
48 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
49 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
50 |
38
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
51 STATE_START = 0 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
52 STATE_PRED = 1 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
53 STATE_STR_SQ = 2 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
54 STATE_STR_DQ = 3 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
55 STATE_BKSP = 4 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
56 STATE_STOP = 5 |
38
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
57 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
58 def _path_split(path): |
38
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
59 stk = [] |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
60 idx = 0 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
61 left = 0 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
62 state = STATE_START |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
63 parts = [] |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
64 while True: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
65 mo = _reo_nest_chars.search(path, idx) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
66 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
67 if mo == None: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
68 parts.append(path[left:]) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
69 break |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
70 |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
71 ch = mo.group() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
72 idx = mo.end() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
73 if state == STATE_START: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
74 if ch == '/': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
75 parts.append(path[left:idx - 1]) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
76 left = idx |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
77 elif ch == '[': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
78 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
79 state = STATE_PRED |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
80 elif ch == '\'': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
81 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
82 state = STATE_STR_SQ |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
83 elif ch == '"': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
84 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
85 state = STATE_STR_DQ |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
86 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
87 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
88 elif state == STATE_STR_SQ: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
89 if ch == '\'': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
90 state = stk.pop() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
91 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
92 elif ch == '\\': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
93 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
94 state = STATE_BKSP |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
95 bksp_idx = idx |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
96 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
97 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
98 elif state == STATE_STR_DQ: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
99 if ch == '"': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
100 state = stk.pop() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
101 elif ch == '\\': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
102 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
103 state = STATE_BKSP |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
104 bksp_idx = idx |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
105 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
106 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
107 elif state == STATE_PRED: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
108 if ch == '[': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
109 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
110 state = STATE_PRED |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
111 elif ch == '\'': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
112 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
113 state = STATE_STR_SQ |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
114 elif ch == '"': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
115 stk.append(state) |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
116 state = STATE_STR_DQ |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
117 elif ch == ']': |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
118 state = stk.pop() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
119 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
120 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
121 elif state == STATE_BKSP: |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
122 if idx != (bksp_idx + 1): |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
123 idx = mo.start() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
124 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
125 state = stk.pop() |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
126 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
127 pass |
0766bd54c9d3
Formally parse path into parts in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
37
diff
changeset
|
128 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
129 return parts |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
130 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
131 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
132 def _path_parse_preds(path): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
133 stk = [] |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
134 idx = 0 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
135 state = STATE_START |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
136 name = None |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
137 preds = [] |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
138 while True: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
139 mo = _reo_nest_chars.search(path, idx) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
140 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
141 if mo == None: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
142 break |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
143 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
144 ch = mo.group() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
145 idx = mo.end() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
146 if state in (STATE_START, STATE_STOP): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
147 if ch == '[': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
148 name = path[:idx - 1] |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
149 left = idx |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
150 stk.append(STATE_STOP) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
151 state = STATE_PRED |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
152 elif ch == '\'': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
153 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
154 state = STATE_STR_SQ |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
155 elif ch == '"': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
156 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
157 state = STATE_STR_DQ |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
158 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
159 else: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
160 raise ValueError, 'invalid structpath string' |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
161 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
162 elif state == STATE_STR_SQ: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
163 if ch == '\'': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
164 state = stk.pop() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
165 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
166 elif ch == '\\': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
167 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
168 state = STATE_BKSP |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
169 bksp_idx = idx |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
170 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
171 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
172 elif state == STATE_STR_DQ: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
173 if ch == '"': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
174 state = stk.pop() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
175 elif ch == '\\': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
176 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
177 state = STATE_BKSP |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
178 bksp_idx = idx |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
179 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
180 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
181 elif state == STATE_PRED: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
182 if ch == '[': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
183 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
184 state = STATE_PRED |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
185 elif ch == '\'': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
186 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
187 state = STATE_STR_SQ |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
188 elif ch == '"': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
189 stk.append(state) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
190 state = STATE_STR_DQ |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
191 elif ch == ']': |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
192 state = stk.pop() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
193 if state == STATE_STOP: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
194 preds.append(path[left:idx - 1]) |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
195 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
196 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
197 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
198 elif state == STATE_BKSP: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
199 if idx != (bksp_idx + 1): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
200 idx = mo.start() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
201 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
202 state = stk.pop() |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
203 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
204 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
205 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
206 if state not in (STATE_START, STATE_STOP): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
207 raise ValueError, 'invalid structpath string' |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
208 if state == STATE_STOP and idx != len(path): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
209 raise ValueError, 'invalid structpath string' |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
210 if state == STATE_START: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
211 name = path |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
212 pass |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
213 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
214 return name, preds |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
215 |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
216 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
217 def _is_abs(path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
218 if len(path_parts) == 0: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
219 return False |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
220 return path_parts[0] == '' |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
221 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
222 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
223 def _rel_of_abs(path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
224 return path_parts[1:] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
225 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
226 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
227 def _is_class(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
228 return part.startswith('.') |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
229 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
230 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
231 def _class_name(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
232 return part[1:] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
233 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
234 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
235 def _is_parent_name(part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
236 return part == '..' |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
237 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
238 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
239 def _eval_obj_pred(ctx, obj, pred): |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
240 ns_global = {} |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
241 for attr in dir(obj): |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
242 if attr.startswith('_'): |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
243 continue |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
244 v = _obj_attr(obj, attr) |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
245 ns_global[attr] = v |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
246 pass |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
247 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
248 truth_v = eval(pred, ns_global) |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
249 return truth_v |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
250 |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
251 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
252 def _eval_obj_preds(ctx, obj, preds): |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
253 for pred in preds: |
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
254 if not pred: |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
255 continue |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
256 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
257 if not _eval_obj_pred(ctx, obj, pred): |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
258 return False |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
259 pass |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
260 return True |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
261 |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
262 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
263 def _obj_attr(obj, attrname): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
264 if isinstance(obj, list): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
265 idx = int(attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
266 return obj[idx] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
267 elif isinstance(obj, dict): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
268 key = eval(attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
269 return obj[key] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
270 return getattr(obj, attrname) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
271 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
272 |
37
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
273 def _obj_attr_objs(obj, attrname): |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
274 if attrname == '*': |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
275 if isinstance(obj, list): |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
276 return obj |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
277 elif isinstance(obj, dict): |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
278 return list(obj.values()) |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
279 else: |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
280 raise ValueError, '\'*\' is invliad here' |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
281 pass |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
282 return [_obj_attr(obj, attrname)] |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
283 |
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
284 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
285 def _handle_path_part_obj(ctx, part, obj): |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
286 attr, preds = _path_parse_preds(part) |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
287 |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
288 if _is_parent_name(attr): |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
289 new_objs = [ctx.get_parent(obj)] |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
290 elif _is_class(attr): |
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
291 class_name = _class_name(attr) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
292 new_objs = ctx.class_instances[class_name] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
293 else: |
34
fe1ebf0c3d40
test get_parent() for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
32
diff
changeset
|
294 try: |
37
ee8aeb299f10
Support wild (*) character in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
36
diff
changeset
|
295 new_objs = _obj_attr_objs(obj, attr) |
34
fe1ebf0c3d40
test get_parent() for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
32
diff
changeset
|
296 except AttributeError: |
fe1ebf0c3d40
test get_parent() for structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
32
diff
changeset
|
297 return [] |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
298 pass |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
299 |
39
aa05cc7ccd0d
Serious implementation for parsing predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
38
diff
changeset
|
300 new_objs = filter((lambda x: _eval_obj_preds(ctx, x, preds)), new_objs) |
35
2f9e7f03dbf7
Support predicates in structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
34
diff
changeset
|
301 |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
302 return new_objs |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
303 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
304 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
305 def _handle_path_part(ctx, part): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
306 from itertools import chain |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
307 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
308 if not ctx.objs: |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
309 ctx = ctx.__class__([ctx.root], ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
310 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
311 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
312 objss = [_handle_path_part_obj(ctx, part, obj) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
313 for obj in ctx.objs] |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
314 objs = [o for o in chain(*objss)] |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
315 new_ctx = ctx.__class__(objs, ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
316 return new_ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
317 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
318 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
319 def _handle_path_parts(ctx, path_parts): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
320 if _is_abs(path_parts): |
32
9bac21d401fe
Make get_parent() as a method of structpath.context
Thinker K.F. Li <thinker@codemud.net>
parents:
31
diff
changeset
|
321 ctx = ctx.__class__([ctx.root], ctx) |
31
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
322 path_parts = _rel_of_abs(path_parts) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
323 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
324 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
325 if len(path_parts) == 1 and path_parts[0] == '': |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
326 return ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
327 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
328 for path_part in path_parts: |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
329 ctx = _handle_path_part(ctx, path_part) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
330 pass |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
331 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
332 return ctx |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
333 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
334 |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
335 def find_objs_path(ctx, path): |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
336 path_parts = _path_split(path) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
337 rctx = _handle_path_parts(ctx, path_parts) |
aed662c820d8
xpath like query structpath.py
Thinker K.F. Li <thinker@codemud.net>
parents:
diff
changeset
|
338 return rctx.objs |