コード例 #1
0
ファイル: xelement.py プロジェクト: thatmattbone/betterxml
 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']
コード例 #2
0
ファイル: xelement.py プロジェクト: thatmattbone/betterxml
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
コード例 #3
0
ファイル: xelement2.py プロジェクト: thatmattbone/betterxml
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