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
|
########################################################################
#
# File Name: ParsedStepPattern.py
#
#
"""
Parse class to handle XSLT StepPatterns
WWW: http://4suite.com/4XSLT e-mail: support@4suite.com
Copyright (c) 1999-2000 Fourthought Inc, USA. All Rights Reserved.
See http://4suite.com/COPYRIGHT for license and copyright information
"""
from xml.dom import Node
from xml.xpath import ParsedToken
from xml.xslt import XsltException, Error
class StepPattern:
def __init__(self, nodeTest, axisType, parent=None, parentAxis=None):
self.nodeTest = nodeTest
self.axisType = axisType
self.priority = nodeTest.priority
self.parent = parent
self.parentAxis = parentAxis
def getShortcut(self):
return (self.nodeTest, self.axisType)
def match(self, context, node, nodeType):
raise Exception('subclass should override')
def pprint(self, indent=''):
print indent + str(self)
self.nodeTest.pprint(indent + ' ')
self.parent and self.parent.pprint(indent + ' ')
def __str__(self):
return '<%s at %x: %s>' % (
self.__class__.__name__,
id(self),
repr(self))
def __repr__(self):
st = (self.axisType == Node.ATTRIBUTE_NODE and '@' or '')
return st + repr(self.nodeTest)
class ParentStepPattern(StepPattern):
def getShortcut(self):
return (self, self.axisType)
def match(self, context, node, axisType):
# Called when there is another step following
if self.nodeTest.match(context, node, self.axisType):
if node.parentNode:
node = node.parentNode
elif node.nodeType == Node.ATTRIBUTE_NODE:
node = node.ownerElement
return self.parent.match(context, node, self.parentAxis)
return 0
def __repr__(self):
st = '/' + (self.axisType == Node.ATTRIBUTE_NODE and '@' or '')
return repr(self.parent) + st + repr(self.nodeTest)
class RootParentStepPattern(StepPattern):
def getShortcut(self):
return (self, self.axisType)
def match(self, context, node, axisType):
if self.nodeTest.match(context, node, axisType):
return node.parentNode == node.ownerDocument
return 0
def __repr__(self):
prefix = '/' + (self.axisType == Node.ATTRIBUTE_NODE and '@' or '')
suffix = self.parent and repr(self.parent) or ''
return prefix + repr(self.nodeTest) + suffix
class AncestorStepPattern(StepPattern):
def getShortcut(self):
return (self, self.axisType)
def match(self, context, node, axisType):
# Called when there is another step following
if self.nodeTest.match(context, node, self.axisType):
if node.parentNode:
node = node.parentNode
elif node.nodeType == Node.ATTRIBUTE_NODE:
node = node.ownerElement
while node:
if self.parent.match(context, node, self.parentAxis):
return 1
node = node.parentNode
return 0
def __repr__(self):
st = '//' + (self.axisType == Node.ATTRIBUTE_NODE and '@' or '')
return repr(self.parent) + st + repr(self.nodeTest)
class PredicateStepPattern:
def __init__(self, nodeTest, axisType, predicates):
self.nodeTest = nodeTest
self.axisType = axisType
self.predicates = predicates
self.priority = 0.5
def getShortcut(self):
return (self, None)
def match(self, context, node, axisType):
if node.parentNode:
parent = node.parentNode
node_set = parent.childNodes
elif node.nodeType == Node.ATTRIBUTE_NODE == self.axisType:
parent = node.ownerElement
node_set = parent.attributes.values()
else:
# Must be a document, it only matches '/'
return 0
# Pass through the NodeTest
node_set = filter(lambda node,
match=self.nodeTest.match,
context=context,
principalType=self.axisType:
match(context, node, principalType),
node_set)
# Our axes are forward only
if node_set:
original = context.node
context.node = parent
node_set = self.predicates.filter(node_set, context, 0)
context.node = original
return node in node_set
def pprint(self, indent=''):
print indent + '<%s at %x: %s>' % (
self.__class__.__name__,
id(self),
repr(self))
self.nodeTest.pprint(indent + ' ')
self.predicates.pprint(indent + ' ')
def __repr__(self):
prefix = self.axisType == Node.ATTRIBUTE_NODE and '@' or ''
return prefix + repr(self.nodeTest) + repr(self.predicates)
|