""" $Id: XML.py,v 1.3 2000/10/22 18:21:57 kmacleod Exp $ """ import Orchard import types import string DocumentType = "DocumentType" class Document(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'contents'): self.contents = [] def _GET_node_type(self): return DocumentType def _GET_root(self): contents = self.contents for item in contents: if item.node_type is ElementType: return item return None def _SET_root(self, value): raise Orchard.AttributeReadOnlyError ElementType = "ElementType" class Element(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'local_name'): raise TypeError, 'missing name or local_name argument' if not hasattr(self, 'contents'): self.contents = [] if not hasattr(self, 'attributes'): self.attributes = [] if not hasattr(self, 'namespace_uri'): self.namespace_uri = None def _GET_node_type(self): return ElementType def _GET_name(self): if hasattr(self, 'prefix'): return self.prefix + ":" + self.local_name else: return self.local_name def _SET_name(self, name): name_parts = string.split(name, ':') if len(name_parts) == 1: if hasattr(self, 'prefix'): delattr(self, 'prefix') self.local_name = name_parts[0] elif len(name_parts) == 2: self.prefix = name_parts[0] self.local_name = name_parts[1] else: raise TypeError, "too many colons (':') in an name" def _SET_attributes(self, attributes): if ( type(attributes) == types.ListType or type(attributes) == types.TupleType): new_attributes = AttributeMap() for attribute in attributes: new_attributes[(attribute.namespace_uri, attribute.local_name)] = attribute self._values[(None, 'attributes')] = new_attributes else: raise TypeError, "Element.attributes: can only assign Lists or Tuples" AttributeMapType = "AttributeMapType" class AttributeMap(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) def __len__(self): return len(self._values) def __getattr__(self, name): if name[0] == '_': raise AttributeError try: return self.__getitem__(name) except KeyError: raise AttributeError def __setattr__(self, name, value): self.__setitem__(name, value) def __getitem__(self, key): if ( type(key) == types.TupleType or string.find(key, ':') == -1 ): return Orchard.Node.__getitem__(self, key) # note: the return value is indeterminate if there is more # than one attribute with the same prefix and localname (but # different namespace, which is allowed) (prefix, local_name) = string.split(key, ':') for attr in self._values.values(): if ( hasattr(attr, 'prefix') and attr.prefix == prefix and attr.local_name == local_name ): return attr raise KeyError def __setitem__(self, key, value): if type(key) == types.TupleType: namespace_uri = key[0] local_name = key[1] if ( namespace_uri != None and value.namespace_uri == None ): value.namespace_uri = namespace_uri if not hasattr(value, 'local_name'): value.local_name = local_name Orchard.Node.__setitem__(self, (value.namespace_uri, value.local_name), value) elif string.find(key, ':') == -1: if not hasattr(value, 'local_name'): value.local_name = key Orchard.Node.__setitem__(self, (value.namespace_uri, value.local_name), value) else: raise TypeError, "can't store to qualified name" AttributeType = "AttributeType" class Attribute(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'local_name'): raise TypeError, 'missing name or local_name argument' if not hasattr(self, 'value'): self.value = "" if not hasattr(self, 'namespace_uri'): self.namespace_uri = None def _GET_node_type(self): return AttributeType def _GET_name(self): if hasattr(self, 'prefix'): return self.prefix + ":" + self.local_name else: return self.local_name def _SET_name(self, name): name_parts = string.split(name, ':') if len(name_parts) == 1: if hasattr(self, 'prefix'): delattr(self, 'prefix') self.local_name = name_parts[0] elif len(name_parts) == 2: self.prefix = name_parts[0] self.local_name = name_parts[1] else: raise TypeError, "too many colons (':') in an name" CharactersType = "CharactersType" class Characters(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'data'): self.data = "" def _GET_node_type(self): return CharactersType CommentType = "CommentType" class Comment(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'data'): self.data = "" def _GET_node_type(self): return CommentType ProcessingInstructionType = "ProcessingInstructionType" class ProcessingInstruction(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'data'): self.data = "" def _GET_node_type(self): return ProcessingInstructionType IgnorableWhitespaceType = "IgnorableWhitespaceType" class IgnorableWhitespace(Orchard.Node): def __init__(self, *positional_args, **keyword_args): positional_args = (self,) + positional_args apply(Orchard.Node.__init__, positional_args, keyword_args) if not hasattr(self, 'data'): self.data = "" def _GET_node_type(self): return IgnorableWhitespaceType def load(source, **keyword_args): import Orchard.Parsers.SAX builder = Orchard.TreeBuilder() parser = Orchard.Parsers.SAX.SAX( handler=builder ) return apply(parser.parse, (source,), keyword_args)