Mercurial > genshi > genshi-test
comparison markup/path.py @ 70:0498da8e5de7
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 | e9a3930f8823 |
children | b0fd16111f2e |
comparison
equal
deleted
inserted
replaced
69:e9a3930f8823 | 70:0498da8e5de7 |
---|---|
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 |