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)
|