Viewing file: ParsedNodeTest.py (5.85 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
######################################################################## # $Header: /var/local/cvsroot/4Suite/Ft/Xml/XPath/ParsedNodeTest.py,v 1.10 2005/01/01 17:22:06 uogbuji Exp $ """ A parsed token that represents a node test.
Copyright 2004 Fourthought, Inc. (USA). Detailed license and copyright information: http://4suite.org/COPYRIGHT Project home, documentation, distributions: http://4suite.org/ """
from xml.dom import Node
from Ft.Xml.XPath import RuntimeException from Ft.Xml.XPath.Types import g_xpathRecognizedNodes
def ParsedNameTest(name): if name == '*': return PrincipalTypeTest() index = name.find(':') if index == -1: return LocalNameTest(name) elif name[index:] == ':*': return NamespaceTest(name[:index]) return QualifiedNameTest(name[:index], name[index+1:])
def ParsedNodeTest(test, literal=None): if literal: if test != 'processing-instruction': raise SyntaxError('Literal only allowed in processing-instruction') return ProcessingInstructionNodeTest(literal) return g_classMap[test]()
class NodeTestBase:
priority = -0.5 nodeType = None
def getQuickKey(self, namespaces): """ Returns a tuple that indicates the expected node type and, if applicable, the expected name. """ return (self.nodeType, None)
def match(self, context, node, principalType=Node.ELEMENT_NODE): """ The principalType is discussed in section [2.3 Node Tests] of the XPath 1.0 spec. Only attribute and namespace axes differ from the default of elements. """ return node.nodeType == self.nodeType
def pprint(self, indent): print indent + str(self)
def __str__(self): return '<%s at %x: %s>' % ( self.__class__.__name__, id(self), repr(self), )
class NodeTest(NodeTestBase):
def match(self, context, node, principalType=Node.ELEMENT_NODE): return node.nodeType in g_xpathRecognizedNodes
def __repr__(self): return 'node()'
class CommentNodeTest(NodeTestBase):
nodeType = Node.COMMENT_NODE
def __repr__(self): return 'comment()'
class TextNodeTest(NodeTestBase):
nodeType = Node.TEXT_NODE
def __repr__(self): return 'text()'
class ProcessingInstructionNodeTest(NodeTestBase):
nodeType = Node.PROCESSING_INSTRUCTION_NODE
def __init__(self, target=None): if target: self.priority = 0 if target[0] not in ['"', "'"]: raise SyntaxError("Invalid literal: %s" % target) self.target = target[1:-1] else: self.priority = -0.5 self.target = ''
def match(self, context, node, principalType=Node.ELEMENT_NODE): if node.nodeType != self.nodeType: return 0 if self.target: return node.target == self.target return 1
def __repr__(self): if self.target: target = repr(self.target) else: target = '' return 'processing-instruction(%s)' % target
# Name tests
class PrincipalTypeTest(NodeTestBase):
nodeType = Node.ELEMENT_NODE
def match(self, context, node, principalType=Node.ELEMENT_NODE): return node.nodeType == principalType
def __repr__(self): return '*'
class LocalNameTest(NodeTestBase):
nodeType = Node.ELEMENT_NODE
def __init__(self, name): self.priority = 0 self._name = name
def getQuickKey(self, namespaces): return (self.nodeType, (None, self._name))
def match(self, context, node, principalType=Node.ELEMENT_NODE): # NameTests do not use the default namespace, just as attributes if node.nodeType == principalType and not node.namespaceURI: return node.localName == self._name return 0
def __repr__(self): return self._name
class NamespaceTest(NodeTestBase):
nodeType = Node.ELEMENT_NODE
def __init__(self, prefix): self.priority = -0.25 self._prefix = prefix
def getQuickKey(self, namespaces): # By specifing a name of None, this test will fall into the 'general' # category for the principal type return (self.nodeType, None)
def match(self, context, node, principalType=Node.ELEMENT_NODE): if node.nodeType != principalType: return 0 try: return node.namespaceURI == context.processorNss[self._prefix] except KeyError: raise RuntimeException(RuntimeException.UNDEFINED_PREFIX, self._prefix)
def __repr__(self): return self._prefix + ':*'
class QualifiedNameTest(NodeTestBase):
nodeType = Node.ELEMENT_NODE
def __init__(self, prefix, localName): self.priority = 0 self._prefix = prefix self._localName = localName
def getQuickKey(self, namespaces): try: namespace = namespaces[self._prefix] except KeyError: raise RuntimeException(RuntimeException.UNDEFINED_PREFIX, self._prefix) return (self.nodeType, (namespace, self._localName))
def match(self, context, node, principalType=Node.ELEMENT_NODE): if node.nodeType == principalType: if node.localName == self._localName: try: return node.namespaceURI == context.processorNss[self._prefix] except KeyError: raise RuntimeException(RuntimeException.UNDEFINED_PREFIX, self._prefix) return 0
def __repr__(self): return self._prefix + ':' + self._localName
g_classMap = { 'node' : NodeTest, 'comment' : CommentNodeTest, 'text' : TextNodeTest, 'processing-instruction' : ProcessingInstructionNodeTest, }
|