######################################################################## # # File Name: XPointer.py # # Docs: http://docs.4suite.org/XPointer/XPointer.py.html # """ A Parsed Token that represents a list of XPointers WWW: http://4suite.org/XPointer 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, XML_NAMESPACE, XMLNS_NAMESPACE from Ft.Xml.XPointer import XPtrContext from Ft.Xml.Lib.XmlString import XmlStrStrip, IsNCName __all__ = ['Pointer', 'Shorthand', 'SchemeBased', 'PointerPart', 'ElementScheme', 'XmlnsScheme', 'XPointerScheme', 'Scheme', ] import XPtrExprParserc _xpointerSchemeParser = XPtrExprParserc.XPtrExprParser() del XPtrExprParserc class Pointer: def pprint(self, indent=''): print indent + str(self) def __str__(self): return "<%s at %s: %r>" % (self.__class__.__name__, id(self), self) def __repr__(self): raise NotImplementedError class Shorthand(Pointer): def __init__(self, identifier): self.identifier = identifier def select(self, context): doc = context.node.rootNode element = doc.getElementById(self.identifier) if element is None: return [] return [element] def __repr__(self): return self.identifier class SchemeBased(Pointer): def __init__(self, parts): self.parts = parts def select(self, context): for part in self.parts: node_set = part.evaluate(context) if node_set: return node_set # No schemes found an node return [] def pprint(self, indent=''): print indent + str(self) for part in self.parts: part.pprint(indent + ' ') def __repr__(self): return ' '.join(map(repr, self.parts)) class PointerPart(Pointer): """ Implementation of an unsupported XPointer scheme. """ # The constructor is not needed by subclasses def __init__(self, name, data): self.name = name self.data = data def evaluate(self, context): return [] def pprint(self, indent=''): print indent + str(self) def __str__(self): return "<%s at %s: %r>" % (self.__class__.__name__, id(self), self) def __repr__(self): return '%s(%s)' % (self.name, self.data) class ElementScheme(PointerPart): """ Implementation of XPointer element() scheme. """ def __init__(self, name, data): sequence = data.split('/') self.identifier = sequence[0] if self.identifier and not IsNCName(self.identifier): raise SyntaxError("parse error, expecting NCName or '/'") self.sequence = [] for item in sequence[1:]: try: item = int(item) except ValueError: item = -1 if item <= 0: raise SyntaxError('parse error, expecting Integer') self.sequence.append(item) return def evaluate(self, context): node = context.node.rootNode if self.identifier: node = node.getElementById(self.identifier) if node is None: return [] for index in self.sequence: elements = [ child for child in node.childNodes if child.nodeType == Node.ELEMENT_NODE ] try: node = elements[index-1] except IndexError: return [] return [node] def __repr__(self): result = self.identifier for index in self.sequence: result = result + '/%d' % index return 'element(%s)' % result class XmlnsScheme(PointerPart): """ Implementation of XPointer xmlns() scheme. """ def __init__(self, name, data): try: prefix, uri = data.split('=', 1) except: raise SyntaxError('parse error, expected =') else: prefix = XmlStrStrip(prefix) uri = XmlStrStrip(uri) if not (prefix and IsNCName(prefix)): raise SyntaxError('parse error, expected NCName') if not uri: raise SyntaxError('parse error, expected EscapedNamespaceName') self.prefix = prefix self.uri = uri def evaluate(self, context): if self.prefix != u'xml' and self.uri not in (XML_NAMESPACE, XMLNS_NAMESPACE): context.processorNss[self.prefix] = self.uri return [] def __repr__(self): return 'xmlns(%s=%s)' % (self.prefix, self.uri) class XPointerScheme(PointerPart): """ Implementation of XPointer xpointer() scheme. """ def __init__(self, name, data): self.expr = _xpointerSchemeParser.parse(data) def evaluate(self, context): return self.expr.evaluate(context) def pprint(self, indent=''): print indent + str(self) self.expr.pprint(indent+' ') def __repr__(self): return 'xpointer(%r)' % self.expr def Scheme(name, data): try: scheme = Schemes[name] except KeyError: scheme = PointerPart return scheme(name, data) Schemes = { 'element' : ElementScheme, 'xmlns' : XmlnsScheme, 'xpointer' : XPointerScheme, }