1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
|
########################################################################
#
# File Name: ParsedAxisSpecifier.py
#
#
"""
A Parsed token that represents an acis specifier on the parsed tree.
WWW: http://4suite.org/XPATH e-mail: support@4suite.org
Copyright (c) 2000-2001 Fourthought Inc, USA. All Rights Reserved.
See http://4suite.org/COPYRIGHT for license and copyright information
"""
from xml.dom import Node
from xml.xpath import g_xpathRecognizedNodes
from xml.xpath import NAMESPACE_NODE
from xml.xpath import Util
from xml.xpath import NamespaceNode
from xml.dom.ext import GetAllNs
import string
def ParsedAxisSpecifier(axis):
try:
return g_classMap[axis](axis)
except KeyError:
raise SyntaxError("Invalid axis: %s" % axis)
class AxisSpecifier:
principalType = Node.ELEMENT_NODE
def __init__(self, axis):
self._axis = axis
def select(self, context, nodeTest):
"""
Always returns a tuple of node-set and 0 if forward, 1 if reverse.
"""
return ([], 0)
def descendants(self, context, nodeTest, node, nodeSet):
"""Select all of the descendants from the context node"""
for child in node.childNodes:
if nodeTest(context, child, self.principalType):
nodeSet.append(child)
if child.childNodes:
self.descendants(context, nodeTest, child, nodeSet)
return (nodeSet, 0)
def pprint(self, indent=''):
print indent + str(self)
def __str__(self):
return '<AxisSpecifier at %x: %s>' % (id(self), repr(self))
def __repr__(self):
"""Always displays verbose expression"""
return self._axis
class ParsedAncestorAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the ancestors including the root"""
nodeSet = []
parent = ((context.node.nodeType == Node.ATTRIBUTE_NODE) and
context.node.ownerElement or context.node.parentNode)
while parent:
if nodeTest(context, parent, self.principalType):
nodeSet.append(parent)
parent = parent.parentNode
nodeSet.reverse()
return (nodeSet, 1)
class ParsedAncestorOrSelfAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the ancestors including ourselves through the root"""
node = context.node
if nodeTest(context, node, self.principalType):
nodeSet = [node]
else:
nodeSet = []
parent = ((node.nodeType == Node.ATTRIBUTE_NODE) and
node.ownerElement or node.parentNode)
while parent:
if nodeTest(context, parent, self.principalType):
nodeSet.append(parent)
parent = parent.parentNode
nodeSet.reverse()
return (nodeSet, 1)
class ParsedAttributeAxisSpecifier(AxisSpecifier):
principalType = Node.ATTRIBUTE_NODE
def select(self, context, nodeTest):
"""Select all of the attributes from the context node"""
attrs = context.node.attributes
rt = filter(lambda attr, test=nodeTest, context=context, pt=self.principalType:
test(context, attr, pt),
attrs and attrs.values() or [])
return (rt, 0)
class ParsedChildAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the children of the context node"""
rt = filter(lambda node, test=nodeTest, context=context, pt=self.principalType:
test(context, node, pt),
list(context.node.childNodes))
return (rt, 0)
class ParsedDescendantOrSelfAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select the context node and all of its descendants"""
if nodeTest(context, context.node, self.principalType):
nodeSet = [context.node]
else:
nodeSet = []
self.descendants(context, nodeTest, context.node, nodeSet)
return (nodeSet, 0)
class ParsedDescendantAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
nodeSet = []
self.descendants(context, nodeTest, context.node, nodeSet)
return (nodeSet, 0)
class ParsedFollowingSiblingAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the siblings that follow the context node"""
result = []
sibling = context.node.nextSibling
while sibling:
if nodeTest(context, sibling, self.principalType):
result.append(sibling)
sibling = sibling.nextSibling
return (result, 0)
class ParsedFollowingAxisSpecifier(AxisSpecifier):
def select(self,context, nodeTest):
"""
Select all of the nodes the follow the context node,
not including descendants.
"""
result = []
curr = context.node
while curr != (context.node.ownerDocument or context.node):
sibling = curr.nextSibling
while sibling:
if nodeTest(context, sibling, self.principalType):
result.append(sibling)
self.descendants(context, nodeTest, sibling, result)
sibling = sibling.nextSibling
curr = ((curr.nodeType == Node.ATTRIBUTE_NODE) and
curr.ownerElement or curr.parentNode)
return (result, 0)
class ParsedNamespaceAxisSpecifier(AxisSpecifier):
principalType = NAMESPACE_NODE
def select(self, context, nodeTest):
"""Select all of the namespaces from the context"""
if context.node.nodeType != Node.ELEMENT_NODE:
return ([], 0)
result = []
#nss = context.nss()
nss = GetAllNs(context.node)
for prefix in nss.keys():
nsNode = NamespaceNode.NamespaceNode(
prefix, nss[prefix],
(context.node.ownerDocument or context.node)
)
if nodeTest(context, nsNode, self.principalType):
result.append(nsNode)
return (result, 0)
class ParsedParentAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select the parent of the context node"""
parent = ((context.node.nodeType == Node.ATTRIBUTE_NODE) and
context.node.ownerElement or context.node.parentNode)
if parent and nodeTest(context, parent, self.principalType):
result = [parent]
else:
result = []
return (result, 1)
class ParsedPrecedingSiblingAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the siblings that precede the context node"""
result = []
sibling = context.node.previousSibling
while sibling:
if nodeTest(context, sibling, self.principalType):
result.append(sibling)
sibling = sibling.previousSibling
# Put the list in document order
result.reverse()
return (result, 1)
class ParsedPrecedingAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select all of the nodes the precede the context node, not including ancestors"""
# Create a list of lists of descendants of the nodes
# that precede the context node. (reverse doc order)
doc_list = []
curr = context.node
while curr:
sib = curr.previousSibling
while sib:
result = []
if nodeTest(context, sib, self.principalType):
result = [sib]
self.descendants(context, nodeTest, sib, result)
doc_list.append(result)
sib = sib.previousSibling
curr = curr.nodeType == Node.ATTRIBUTE_NODE and curr.ownerElement or curr.parentNode
# Create a single list in document order
result = []
for i in range(1, len(doc_list)+1):
result.extend(doc_list[-i])
return (result, 1)
class ParsedSelfAxisSpecifier(AxisSpecifier):
def select(self, context, nodeTest):
"""Select the context node"""
if nodeTest(context, context.node, self.principalType):
return ([context.node], 0)
return ([], 0)
g_classMap = {
'ancestor' : ParsedAncestorAxisSpecifier,
'ancestor-or-self' : ParsedAncestorOrSelfAxisSpecifier,
'child' : ParsedChildAxisSpecifier,
'parent' : ParsedParentAxisSpecifier,
'descendant' : ParsedDescendantAxisSpecifier,
'descendant-or-self' : ParsedDescendantOrSelfAxisSpecifier,
'attribute' : ParsedAttributeAxisSpecifier,
'following' : ParsedFollowingAxisSpecifier,
'following-sibling' : ParsedFollowingSiblingAxisSpecifier,
'preceding' : ParsedPrecedingAxisSpecifier,
'preceding-sibling' : ParsedPrecedingSiblingAxisSpecifier,
'namespace' : ParsedNamespaceAxisSpecifier,
'self' : ParsedSelfAxisSpecifier,
}
|