comparison markup/path.py @ 70:dd73921530e8 trunk

Use `collections.deque` for the template context stack on Python 2.4, which improves performance if there are many context frame pop/push operations.
author cmlenz
date Tue, 11 Jul 2006 17:40:41 +0000
parents c40a5dcd2b55
children 1da51d718391
comparison
equal deleted inserted replaced
69:c40a5dcd2b55 70:dd73921530e8
13 13
14 """Basic support for evaluating XPath expressions against streams.""" 14 """Basic support for evaluating XPath expressions against streams."""
15 15
16 import re 16 import re
17 17
18 from markup.core import QName, Stream 18 from markup.core import QName, Stream, START, END, TEXT
19 19
20 __all__ = ['Path'] 20 __all__ = ['Path']
21 21
22 22
23 class Path(object): 23 class Path(object):
112 Text 112 Text
113 113
114 @param stream: the stream to select from 114 @param stream: the stream to select from
115 @return: the substream matching the path, or an empty stream 115 @return: the substream matching the path, or an empty stream
116 """ 116 """
117 from markup.core import END, START
118
119 stream = iter(stream) 117 stream = iter(stream)
120 def _generate(): 118 def _generate():
121 test = self.test() 119 test = self.test()
122 for kind, data, pos in stream: 120 for kind, data, pos in stream:
123 result = test(kind, data, pos) 121 result = test(kind, data, pos)
210 208
211 class _CurrentElement(_NodeTest): 209 class _CurrentElement(_NodeTest):
212 """Node test that matches the context node.""" 210 """Node test that matches the context node."""
213 axis = 'self' 211 axis = 'self'
214 def __call__(self, kind, *_): 212 def __call__(self, kind, *_):
215 if kind is Stream.START: 213 if kind is START:
216 return True 214 return True
217 return None 215 return None
218 216
219 class _AnyChildElement(_NodeTest): 217 class _AnyChildElement(_NodeTest):
220 """Node test that matches any child element.""" 218 """Node test that matches any child element."""
221 axis = 'child' 219 axis = 'child'
222 def __call__(self, kind, *_): 220 def __call__(self, kind, *_):
223 if kind is Stream.START: 221 if kind is START:
224 return True 222 return True
225 return None 223 return None
226 224
227 class _ChildElementByName(_NodeTest): 225 class _ChildElementByName(_NodeTest):
228 """Node test that matches a child element with a specific tag name.""" 226 """Node test that matches a child element with a specific tag name."""
229 axis = 'child' 227 axis = 'child'
230 def __init__(self, name): 228 def __init__(self, name):
231 self.name = QName(name) 229 self.name = QName(name)
232 def __call__(self, kind, data, _): 230 def __call__(self, kind, data, _):
233 if kind is Stream.START: 231 if kind is START:
234 return data[0].localname == self.name 232 return data[0].localname == self.name
235 return None 233 return None
236 def __repr__(self): 234 def __repr__(self):
237 return '<%s "%s">' % (self.__class__.__name__, self.name) 235 return '<%s "%s">' % (self.__class__.__name__, self.name)
238 236
239 class _AnyAttribute(_NodeTest): 237 class _AnyAttribute(_NodeTest):
240 """Node test that matches any attribute.""" 238 """Node test that matches any attribute."""
241 axis = 'attribute' 239 axis = 'attribute'
242 def __call__(self, kind, data, pos): 240 def __call__(self, kind, data, pos):
243 if kind is Stream.START: 241 if kind is START:
244 text = ''.join([val for _, val in data[1]]) 242 text = ''.join([val for _, val in data[1]])
245 if text: 243 if text:
246 return Stream.TEXT, text, pos 244 return TEXT, text, pos
247 return None 245 return None
248 return None 246 return None
249 247
250 class _AttributeByName(_NodeTest): 248 class _AttributeByName(_NodeTest):
251 """Node test that matches an attribute with a specific name.""" 249 """Node test that matches an attribute with a specific name."""
252 axis = 'attribute' 250 axis = 'attribute'
253 def __init__(self, name): 251 def __init__(self, name):
254 self.name = QName(name) 252 self.name = QName(name)
255 def __call__(self, kind, data, pos): 253 def __call__(self, kind, data, pos):
256 if kind is Stream.START: 254 if kind is START:
257 if self.name in data[1]: 255 if self.name in data[1]:
258 return Stream.TEXT, data[1].get(self.name), pos 256 return TEXT, data[1].get(self.name), pos
259 return None 257 return None
260 return None 258 return None
261 def __repr__(self): 259 def __repr__(self):
262 return '<%s "%s">' % (self.__class__.__name__, self.name) 260 return '<%s "%s">' % (self.__class__.__name__, self.name)
263 261
265 """Abstract node test representing a function.""" 263 """Abstract node test representing a function."""
266 264
267 class _FunctionText(_Function): 265 class _FunctionText(_Function):
268 """Function that returns text content.""" 266 """Function that returns text content."""
269 def __call__(self, kind, data, pos): 267 def __call__(self, kind, data, pos):
270 if kind is Stream.TEXT: 268 if kind is TEXT:
271 return kind, data, pos 269 return kind, data, pos
272 return None 270 return None
273 271
274 class _LiteralString(_NodeTest): 272 class _LiteralString(_NodeTest):
275 """Always returns a literal string.""" 273 """Always returns a literal string."""
276 def __init__(self, value): 274 def __init__(self, value):
277 self.value = value 275 self.value = value
278 def __call__(self, *_): 276 def __call__(self, *_):
279 return Stream.TEXT, self.value, (-1, -1) 277 return TEXT, self.value, (-1, -1)
280 278
281 class _OperatorEq(_NodeTest): 279 class _OperatorEq(_NodeTest):
282 """Equality comparison operator.""" 280 """Equality comparison operator."""
283 def __init__(self, lval, rval): 281 def __init__(self, lval, rval):
284 self.lval = lval 282 self.lval = lval
Copyright (C) 2012-2017 Edgewall Software