Changeset 447

Show
Ignore:
Timestamp:
02/20/03 00:58:36 (6 years ago)
Author:
sholloway
Message:

*** empty log message ***

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/RBFoundation/RBFoundation/XMLNode.py

    r437 r447  
    4848_any = matchall() 
    4949 
    50 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    51  
    5250class matchobj(object): 
    5351    def __init__(self, testcall): 
     
    6058#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    6159 
    62 class xmlattrmixin(object): 
    63     def __getattribute__(self, name): 
    64         """Returns self.attrs[name] when possible.  Use explicit self.attrs[name] for more uniform access.""" 
    65         try: 
    66             return object.__getattribute__(self, name) 
    67         except AttributeError: 
    68             if name in self.attrs: 
    69                 return self.attrs[name] 
    70             else: raise 
    71  
    72     def __setattr__(self, name, value): 
    73         """Sets self.attrs[name] = value when possible.  Use explicit self.attrs[name] for more uniform access.""" 
    74         try: 
    75             # This works because of the __slots__ definition 
    76             object.__setattr__(self, name, value) 
    77         except AttributeError: 
    78             if name in self.attrs: 
    79                 self.attrs[name] = str(value) 
    80             elif not hasattr(self, name): 
    81                 self.attrs[name] = str(value) 
    82             else: raise 
    83  
    84 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    85  
    86 class xmlnode(object): 
     60class xmlnodebase(object):  
     61    pass 
     62 
     63class xmlnode(xmlnodebase): 
    8764    """Simple class to build valid XML. 
    8865    Also has some basic access, query, and iteration methods. 
     
    11794    __slots__ = ['node', 'prefix', 'namespaces', 'elems', 'attrs', 'nodebuilder', 'softspace'] 
    11895    nodebuilder = None 
     96    default_node = None 
    11997    default_attributes = {} 
    12098    default_namespaces = XMLNamespaceMap() 
     
    126104    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    127105 
    128     def __init__(self, node, namespace=None, prefix='', default_namespaces=None, attrlookup=None): 
     106    def __init__(self, node=None, namespace=None, prefix='', default_namespaces=None, attrlookup=None): 
    129107        self.enableattrlookup(attrlookup) 
    130108        if default_namespaces: self.namespaces = default_namespaces 
     
    132110        self.elems = self.default_elements[:] 
    133111        self.attrs = self.default_attributes.copy() 
    134         self.node = node 
     112        self.node = node or self.default_node or self.__class__.__name__ 
    135113        self.namespace = (prefix, namespace) 
    136114        self.softspace = 0 # for compatibility with file-like objects 
     
    246224        if isinstance(elem, basestring): 
    247225            return self.adddata(elem) 
    248         else: return self.addnode(*elem) 
     226        elif isinstance(elem, xmlnodebase): 
     227            # For elements that are prebuilt 
     228            self.elems.append(elem) 
     229            return elem 
     230        else:  
     231            # For building from tuples and lists 
     232            return self.addnode(*elem) 
    249233 
    250234    def setxmlns(self, *args, **kw): 
     
    295279 
    296280    def enumnodes(self, node=_any, namespace=_any, prefix=_any, idxonly=True): 
    297         """Returns a generator to iterate through the matching child node indicies of xmlnode""" 
     281        """Returns a generator to iterate through the matching child node indicies of xmlnode. 
     282        obj.enumnodes(node=_any, namespace=_any, prefix=_any)""" 
     283        idxonly = kw.get('idxonly', None) 
     284        if idxonly is not None: del kw['idxonly'] 
     285        if args or kw: 
     286            match = lambda node=_any, namespace=_any, prefix=_any: node == each.node and namespace == each.namespace and prefix == each.prefix 
     287        else: match = lambda: True 
    298288        idx = 0 
    299289        for each in self.elems: 
    300290            if not isinstance(each, basestring): 
    301                 if node == each.node and namespace == each.namespace and prefix == each.prefix
     291                if match(*args, **kw)
    302292                    if idxonly: yield idx 
    303293                    else: yield idx, each 
    304294            idx += 1 
    305295 
    306     def iternodes(self, node=_any, namespace=_any, prefix=_any): 
    307         """Returns a generator to iterate through the matching child nodes of xmlnode""" 
     296    def iternodes(self, *args, **kw): 
     297        """Returns a generator to iterate through the matching child nodes of xmlnode. 
     298        obj.iternodes(node=_any, namespace=_any, prefix=_any)""" 
     299        if args or kw: 
     300            match = lambda node=_any, namespace=_any, prefix=_any: node == each.node and namespace == each.namespace and prefix == each.prefix 
     301        else: match = lambda: True 
    308302        for each in self.elems: 
    309303            if not isinstance(each, basestring): 
    310                 if node == each.node and namespace == each.namespace and prefix == each.prefix
     304                if match(*args, **kw)
    311305                    yield each 
    312306 
     
    433427 
    434428    def _getnodefactory(self, *args, **kw): 
    435         return self.nodebuilder or self.__class__ 
     429        nodebuilder = kw.get('nodebuilder', None) 
     430        if nodebuilder is not None: 
     431            del kw['nodebuilder'] 
     432            return nodebuilder, args, kw 
     433        else: 
     434            return (self.nodebuilder or self.__class__), args, kw 
    436435 
    437436    def _makenode(self, *args, **kw): 
    438437        kw['default_namespaces'] = self.namespaces.newchain() 
    439         nodebuilder = self._getnodefactory(*args, **kw) 
     438        nodebuilder, args, kw = self._getnodefactory(*args, **kw) 
    440439        result = nodebuilder(*args, **kw) 
    441440        return result 
     
    454453#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    455454 
     455class xmlattrmixin(object): 
     456    def __getattribute__(self, name): 
     457        """Returns self.attrs[name] when possible.  Use explicit self.attrs[name] for more uniform access.""" 
     458        try: 
     459            return object.__getattribute__(self, name) 
     460        except AttributeError: 
     461            if name in self.attrs: 
     462                return self.attrs[name] 
     463            else: raise 
     464 
     465    def __setattr__(self, name, value): 
     466        """Sets self.attrs[name] = value when possible.  Use explicit self.attrs[name] for more uniform access.""" 
     467        try: 
     468            # This works because of the __slots__ definition 
     469            object.__setattr__(self, name, value) 
     470        except AttributeError: 
     471            if name in self.attrs: 
     472                self.attrs[name] = str(value) 
     473            elif not hasattr(self, name): 
     474                self.attrs[name] = str(value) 
     475            else: raise 
     476 
    456477class xmlnodeex(xmlnode, xmlattrmixin): 
    457478    pass 
     
    489510        def _xmlInitComplete(self): pass  
    490511        def _xmlGetElement(self): return self 
    491         def _xmlChildFactory(self, owner, parent, node, attributes, namespacemap):  
    492             return self.__class__ 
    493512        def _toXML(self, *args, **kw): 
    494513            return self.toxml() 
     514 
     515    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    495516 
    496517    class NodeXMLAdaptor(XMLBuilder.XMLBuilderObjectBase): 
    497518        """An external adaptor to bridge between XMLBuilderObjectBase interface and xmlnode""" 
    498519        __slots__ = ['result'] 
    499  
    500         def __init__(self, owner, parent, node, attributes, namespacemap): 
     520        nodebuilder = xmlnode 
     521 
     522        def __init__(self, owner, parent, node, attributes, namespacemap, nodebuilder=xmlnode): 
    501523            prefix = namespacemap.prefix(node[0]) 
    502524            if node[0] in namespacemap or not namespacemap.nextmap: 
    503525                nodename, xmlns = node[1], node[0] 
    504526            else: nodename, xmlns = node[1], None 
    505             self.result = xmlnode(nodename, xmlns, prefix, default_namespaces=namespacemap) 
     527            nodebuilder = nodebuilder or self.nodebuilder 
     528            self.result = nodebuilder(nodename, xmlns, prefix, default_namespaces=namespacemap) 
    506529 
    507530            for key, value in attributes.iteritems(): 
     
    522545        def _xmlGetElement(self):  
    523546            return self.result 
    524         def _xmlChildFactory(self, owner, parent, node, attributes, namespacemap):  
    525             return self.__class__ 
    526547        def _toXML(self, *args, **kw): 
    527548            return self.result.toxml() 
     549 
     550    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     551 
     552    class XMLNodeFactory(object): 
     553        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     554        #~ Constants / Variables / Etc.  
     555        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     556 
     557        nodebuilder = xmlnode 
     558        xmladaptor = NodeXMLAdaptor 
     559 
     560        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     561        #~ Public Methods  
     562        #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
     563 
     564        def __init__(self, nodebuilder=None, xmladaptor=None): 
     565            self.nodebuilder = nodebuilder or self.nodebuilder 
     566            self.xmladaptor = xmladaptor or self.xmladaptor 
     567 
     568        def __call__(self, owner, parent, node, attributes, namespacemap): 
     569            return self.BuildNode 
     570                 
     571        def BuildNode(self, *args, **kw): 
     572            return self.xmladaptor(nodebuilder=self.nodebuilder, *args, **kw) 
     573 
     574    #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    528575 
    529576    class Producer(XMLBuilder.XMLBuilder):