def __init__(self, **options): self.elems = 0 self.attrs = 0 self.pis = 0 self.contextStack = UserStack([]) self.contextStack.push("x") self.document = XDocumentRoot() self.contextStack.push(self.document) self.elementMap = {} self.element_class = {} self.ignoreWhiteSpace = options.has_key('IgnoreWhiteSpace') \ and options['IgnoreWhiteSpace'] in ['true','yes',1,'1'] self.removeWhiteSpace = options.has_key('RemoveWhiteSpace') \ and options['RemoveWhiteSpace'] in ['true','yes',1,'1'] self.createElementMap = options.has_key('CreateElementMap') \ and options['CreateElementMap'] in ['true','yes',1,'1'] self.requireUserClasses = options.has_key('RequireUserClasses') \ and options['RequireUserClasses'] in ['true','yes',1,'1']
class XTreeHandler(ContentHandler): def __init__(self, **options): self.elems = 0 self.attrs = 0 self.pis = 0 self.contextStack = UserStack([]) self.contextStack.push("x") self.document = XDocumentRoot() self.contextStack.push(self.document) self.elementMap = {} self.element_class = {} self.ignoreWhiteSpace = options.has_key('IgnoreWhiteSpace') \ and options['IgnoreWhiteSpace'] in ['true','yes',1,'1'] self.removeWhiteSpace = options.has_key('RemoveWhiteSpace') \ and options['RemoveWhiteSpace'] in ['true','yes',1,'1'] self.createElementMap = options.has_key('CreateElementMap') \ and options['CreateElementMap'] in ['true','yes',1,'1'] self.requireUserClasses = options.has_key('RequireUserClasses') \ and options['RequireUserClasses'] in ['true','yes',1,'1'] def registerElementClass(self, klass, element_name=None): """ register the class that represents the tree node to construct upon encountering an element having element_name. If element_name is None, this means that the element name and class name match. """ if element_name: self.element_class[element_name] = klass else: self.element_class[klass.__name__] = klass def getElementMap(self): return self.elementMap def startElement(self, name, attrs): try: element = self.element_class[name]() except: element = XElement() if element.__class__ == XElement and self.requireUserClasses: raise "No class defined to handle element %s" % str(name) element.setName(name) element.setAttributes(attrs) element.setText('') if self.createElementMap: if not self.elementMap.has_key(name): self.elementMap[name] = [] self.elementMap[name].append(element) element.initialize() self.contextStack.top().linkTo(element) self.contextStack.push(element) self.elems = self.elems+1 self.attrs = self.attrs+len(attrs) def endElement(self, name): popElement = self.contextStack.pop() popElement.finalize(self.contextStack.top()) def characters(self, char): tos = self.contextStack.top() # if self.removeWhiteSpace: # text = ch[start:start+length] # splitText = string.split(text) # if len(tos.text) > 0: # pad = ' ' # else: # pad = '' # for item in splitText: # tos.cdata(pad + item) # pad = ' ' # else: # tos.cdata(ch[start:start+length]) tos.cdata(char) def ignorableWhitespace(self, ch, start, length): if not self.ignoreWhiteSpace: self.contextStack.top().cdata(ch[start:start+length]) def getDocument(self): return self.document def processingInstruction(self, target, data): self.pis = self.pis+1
class XTreeHandler(ContentHandler, ErrorHandler): def __init__(self, **options): self.elems = 0 self.attrs = 0 self.pis = 0 self.contextStack = UserStack([]) #self.contextStack.push("x") self.document = XDocumentRoot() self.contextStack.push(self.document) self.elementMap = {} self.namespaceModules = {} self.default_namespace_uri = None self.previous_namespace_used = None self.ignoreWhiteSpace = options.has_key('IgnoreWhiteSpace') \ and options['IgnoreWhiteSpace'] in ['true','yes',1,'1'] self.removeWhiteSpace = options.has_key('RemoveWhiteSpace') \ and options['RemoveWhiteSpace'] in ['true','yes',1,'1'] self.createElementMap = options.has_key('CreateElementMap') \ and options['CreateElementMap'] in ['true','yes',1,'1'] self.requireUserClasses = options.has_key('RequireUserClasses') \ and options['RequireUserClasses'] in ['true','yes',1,'1'] def registerNamespace(self, userModule): # Every module must contain a function getNamespaceURI() that tells # what URI is managed by the classes in the module. if type(userModule) != types.ModuleType: raise XExceptionGeneral("a module must be specified") moduleName = userModule.__name__ # User module must provide getNamespaceURI(), which returns a # string containing the URI for the XML namespace being provided. getNamespaceURI = getattr(userModule, 'getNamespaceURI', None) if callable(getNamespaceURI): moduleURI = getNamespaceURI() else: raise XExceptionGeneral("%s.getNamespaceURI() missing or not callable" % moduleName) if moduleURI in self.namespaceModules.keys(): raise XExceptionGeneral("%s.getNamespaceURI() duplicate NS definition %s" % (moduleName, moduleURI)) # User module must provide a default class to be instantiated for # any unhandled element name. getDefaultElementClass = getattr(userModule, "getDefaultElementClass", None) if callable(getDefaultElementClass): xeClass = getDefaultElementClass() else: raise XExceptionGeneral("module must provide getDefaultElementClass() definition") if not type(xeClass) == type(XElement) or not issubclass(xeClass, XElement): raise XExceptionGeneral("getDefaultElementClass() in %s must return XElement subclass" % moduleName) getMappings = getattr(userModule, "getMappings", None) if callable(getMappings): mappings = getMappings() else: raise XExceptionGeneral("%s.getMappings() definition missing or not callable") mappings = getMappings() for (elementName, elementClass) in mappings.items(): if type(elementName) != type(''): raise XExceptionGeneral("%s.getMappings() has dict with non-string key" % moduleName) if not type(xeClass) == type(XElement) or \ not issubclass(xeClass, XElement): raise XExceptionGeneral("%s.getMappings() has dict with non-XElement value" % moduleName) self.namespaceModules[moduleURI] = { 'module' : userModule, 'uri' : moduleURI, 'default_class' : xeClass, 'mappings' : mappings } print "registration succeeded for namespace %s" % moduleURI def getElementMap(self): return self.elementMap def getDocument(self): return self.document # SAX/SAX 2 Interfaces def setDocumentLocator(self, locator): self.locator = locator def startDocument(self): self.ns_prefixes = {} pass def endDocument(self): pass def startPrefixMapping(self, prefix, uri): pass def endPrefixMapping(self, prefix): pass def startElementNS(self, name, qname, attrs): (ns_uri, element_name) = name print "startElementNS", ns_uri, element_name, qname # In XElement, it is required to always have a default namespace URI registered. if ns_uri == None: ns_uri = self.default_namespace_uri # Find the module associated with namespace via a previous registerNamespace() call. try: moduleInfo = self.namespaceModules[ns_uri] except: print name, qname, attrs, "default uri", ns_uri raise XExceptionGeneral("unlikely error; unmapped namespace URI %s: Forgot to register it?" % ns_uri) # Map element_name to a user-defined class instance. mappings = moduleInfo['mappings'] try: if mappings == None: elementClass = getattr(moduleInfo['module'], element_name, None) else: elementClass = mappings[element_name] except: elementClass = moduleInfo['default_class'] # if no such mapping was found, and there was no default policy for creating an instance, # then this is a condition for immediate failure. if elementClass == None: raise XExceptionGeeneral("Unable to map element %s in URI %s to a default or user-defined class" % \ (element_name, ns_uri)) # As with XElement 1.0, create the element from the class object. element = elementClass() element.setName(element_name) element.setNamespace(ns_uri) element.setQname(qname) element.setAttributes(attrs) if self.createElementMap: if not self.elementMap.has_key(name): self.elementMap[name] = [] self.elementMap[name].append(element) element.initialize() self.contextStack.top().linkTo(element) self.contextStack.push(element) self.elems = self.elems + 1 self.attrs = self.attrs + len(attrs) def endElementNS(self, name, qname): popElement = self.contextStack.pop() popElement.finalize(self.contextStack.top()) def characters(self, content): self.contextStack.top().cdata(0, content) def showContext(self, context): for x in self.contextStack: print type(x) def ignorableWhitespace(self, content): self.contextStack.top().cdata(1, content) def skippedEntity(self, name): pass def processingInstruction(self, target, data): self.pis = self.pis + 1 def error(self, exception): raise exception def fatalError(self, exception): raise exception def warning(self, exception): raise exception