1
# -*- test-case-name: twisted.words.test.test_xpath -*-
3
# Copyright (c) 2001-2005 Twisted Matrix Laboratories.
4
# See LICENSE for details.
8
import cStringIO as StringIO
13
""" Internal method to determine if an object is a string """
14
return isinstance(s, type('')) or isinstance(s, type(u''))
16
class LiteralValue(str):
17
def value(self, elem):
21
def __init__(self, index):
22
self.index = int(index) - 1
24
def value(self, elem):
25
return elem.children[self.index]
28
def __init__(self, attribname):
29
self.attribname = attribname
30
if self.attribname == "xmlns":
31
self.value = self.value_ns
33
def value_ns(self, elem):
36
def value(self, elem):
37
if self.attribname in elem.attributes:
38
return elem.attributes[self.attribname]
43
def __init__(self, lhs, op, rhs):
47
self.value = self._compareEqual
49
self.value = self._compareNotEqual
51
def _compareEqual(self, elem):
52
return self.lhs.value(elem) == self.rhs.value(elem)
54
def _compareNotEqual(self, elem):
55
return self.lhs.value(elem) != self.rhs.value(elem)
58
""" Internal method which selects the function object """
59
klassname = "_%s_Function" % fname
60
c = globals()[klassname]()
67
def setParams(self, baseValue):
68
self.baseValue = baseValue
70
def value(self, elem):
71
return not self.baseValue.value(elem)
77
def value(self, elem):
83
self.elementName = None
84
self.childLocation = None
86
def matchesPredicates(self, elem):
87
if self.elementName != None and self.elementName != elem.name:
90
for p in self.predicates:
96
def matches(self, elem):
97
if not self.matchesPredicates(elem):
100
if self.childLocation != None:
101
for c in elem.elements():
102
if self.childLocation.matches(c):
109
def queryForString(self, elem, resultbuf):
110
if not self.matchesPredicates(elem):
113
if self.childLocation != None:
114
for c in elem.elements():
115
self.childLocation.queryForString(c, resultbuf)
117
resultbuf.write(str(elem))
119
def queryForNodes(self, elem, resultlist):
120
if not self.matchesPredicates(elem):
123
if self.childLocation != None:
124
for c in elem.elements():
125
self.childLocation.queryForNodes(c, resultlist)
127
resultlist.append(elem)
129
def queryForStringList(self, elem, resultlist):
130
if not self.matchesPredicates(elem):
133
if self.childLocation != None:
134
for c in elem.elements():
135
self.childLocation.queryForStringList(c, resultlist)
137
for c in elem.children:
138
if _isStr(c): resultlist.append(c)
143
self.elementName = None
144
self.childLocation = None
146
def matchesPredicates(self, elem):
147
for p in self.predicates:
148
if not p.value(elem):
152
def listParents(self, elem, parentlist):
153
if elem.parent != None:
154
self.listParents(elem.parent, parentlist)
155
parentlist.append(elem.name)
157
def isRootMatch(self, elem):
158
if (self.elementName == None or self.elementName == elem.name) and \
159
self.matchesPredicates(elem):
160
if self.childLocation != None:
161
for c in elem.elements():
162
if self.childLocation.matches(c):
168
def findFirstRootMatch(self, elem):
169
if (self.elementName == None or self.elementName == elem.name) and \
170
self.matchesPredicates(elem):
171
# Thus far, the name matches and the predicates match,
172
# now check into the children and find the first one
173
# that matches the rest of the structure
174
# the rest of the structure
175
if self.childLocation != None:
176
for c in elem.elements():
177
if self.childLocation.matches(c):
181
# No children locations; this is a match!
184
# Ok, predicates or name didn't match, so we need to start
185
# down each child and treat it as the root and try
187
for c in elem.elements():
190
# No children matched...
193
def matches(self, elem):
194
if self.isRootMatch(elem):
197
# Ok, initial element isn't an exact match, walk
198
# down each child and treat it as the root and try
200
for c in elem.elements():
203
# No children matched...
206
def queryForString(self, elem, resultbuf):
207
raise "UnsupportedOperation"
209
def queryForNodes(self, elem, resultlist):
210
# First check to see if _this_ element is a root
211
if self.isRootMatch(elem):
212
resultlist.append(elem)
214
# Now check each child
215
for c in elem.elements():
216
self.queryForNodes(c, resultlist)
219
def queryForStringList(self, elem, resultlist):
220
if self.isRootMatch(elem):
221
for c in elem.children:
222
if _isStr(c): resultlist.append(c)
223
for c in elem.elements():
224
self.queryForStringList(c, resultlist)
229
def __init__(self, queryStr):
230
self.queryStr = queryStr
231
from twisted.words.xish.xpathparser import parse
232
self.baseLocation = parse('XPATH', queryStr)
235
return self.queryStr.__hash__()
237
def matches(self, elem):
238
return self.baseLocation.matches(elem)
240
def queryForString(self, elem):
241
result = StringIO.StringIO()
242
self.baseLocation.queryForString(elem, result)
243
return result.getvalue()
245
def queryForNodes(self, elem):
247
self.baseLocation.queryForNodes(elem, result)
253
def queryForStringList(self, elem):
255
self.baseLocation.queryForStringList(elem, result)
261
__internedQueries = {}
263
def internQuery(queryString):
264
if queryString not in __internedQueries:
265
__internedQueries[queryString] = XPathQuery(queryString)
266
return __internedQueries[queryString]
268
def matches(xpathstr, elem):
269
return internQuery(xpathstr).matches(elem)
271
def queryForStringList(xpathstr, elem):
272
return internQuery(xpathstr).queryForStringList(elem)
274
def queryForString(xpathstr, elem):
275
return internQuery(xpathstr).queryForString(elem)
277
def queryForNodes(xpathstr, elem):
278
return internQuery(xpathstr).queryForNodes(elem)
280
# Convenience main to generate new xpathparser.py
281
if __name__ == "__main__":
282
from twisted.python import yapps2
283
yapps2.generate('xpathparser.g')