annotate paraspace/structpath.py @ 130:117047deda64

Apply array sorting in inject_redir.py
author Thinker K.F. Li <thinker@codemud.net>
date Tue, 09 Aug 2011 00:07:04 +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