Hello to everybody,
This is XMLToolkit 0,7,BETA.2. I simplified most of the code. There are
a few new features added as well. Now you can use the Binding tool to
Bind XML documents to python objects.

doc = Binding.fromfile('GoogleService.wsdl')
doc.definitions.message
doc.definitions.message[0]
doc.definitions.message[1]
doc.definitions.message.name
doc.definitions.message.name = 'bla bla'
doc.definitions.message = '<h1>Hei I can assign XML to elements that
will be parsed on the fly.</h1> Good!'
doc.definitions.message[1] = OtherBinding
doc.definitions.message[2] = OtherElement
doc.definitions.message[0] = doc.definitions.message[2]
for m in doc.definitions.message:
    print m
    print m.name

doc.xml
doc.xml(encoding = 'utf-8')
doc.xml(encoding = 'utf-8', stream = mystream)
doc.xml(encoding = 'utf-8', file = 'myGoogle.wsdl')
str(doc.xml)
doc.xml.composestream(stream)

As you can see the syntax is similar  to Amara XMLToolkit.
I am still stuck with PEXComposer. If anyone is willing to help me out
with simplifying the code and writing proper Composer to assemble PEX
Objects back to XML, feel free to let me know. It shouldn't take that long.

I need your help more than ever. I believe that XT (XML Toolkit) is
coming nicely and I want to complete it as soon as possible because I
want to move forward and start doing something else. :) So, can you have
a look on the code and suggest any corrections or recommendations? Or
even help me out rewriting some of it. I believe that the current design
is not bad at all, however, somebody may suggest a different approach to
solve a problem.

Thanks.
#    XML Toolkit
#    Copyright (C) 2005  Petko Petkov (GNUCITIZEN) [EMAIL PROTECTED]
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

__version__ = 0,7,'BETA.2'
__author__ = 'Petko Petkov'

__doc__ = """
XML Toolkit

XML Toolkit provides an easy to use, very pythonic approach to xml processing.
Why hard when it can be as simple as Python.
"""

import cStringIO

# XML PARSER

class Parser(object):
        """
        Parser is responsible for parsing xml content. All methods are 
classmethods
        by design. This means that there is not need to instantiate the class.
        """

        # ESCAPE FUNCTIONS

        @classmethod
        def escape(self, string, entities = {}):
                """
                escape(string, entities = {}) -> escaped_string

                Replace special strings with their xml represenation. The 
optional
                entity dictionary is there if additional string substitutions 
are
                required.
                """

                string = string.replace('&', '&amp;')
                string = string.replace('<', '&lt;')
                string = string.replace('>', '&gt;')

                for entity, value in entities.iteritems():
                        string = string.replace(entity, value)

                return string

        @classmethod
        def unescape(self, string, entities = {}):
                """
                unescape(string, entities = {}) -> unescaped_string

                Replace xml entities with their string representation. This 
method is
                a reverse of the escape method.
                """

                string = string.replace('&gt;', '>')
                string = string.replace('&lt;', '<')
                string = string.replace('&amp;', '&')

                for entity, value in entities.iteritems():
                        string = string.replace(value, entity)

                return string

        @classmethod
        def quote(self, string, entities = {}):
                """
                quote(string, entities) -> quoted_string

                Replace special strings with their xml representation and 
quote. This
                function is useful when dealing with attributes. The optional 
entity
                dictionary is there if additional string substitutions are 
required.
                """

                _entities = {}
                _entities.update(entities)
                _entities['"'] = '&quote;'
                _entities["'"] = '&apos;'

                return '"%s"' % self.escape(string, _entities)

        @classmethod
        def unquote(self, string, entities = {}):
                """
                unquote(string, entities) -> unquoted_string

                Replace xml entities with their string representation. This 
method is a
                reverse of the unquote method.
                """

                _entities = {}
                _entities.update(entities)
                _entities['"'] = '&quote;'
                _entities["'"] = '&apos;'

                string = string.strip()

                if string.startswith('"'):
                        string = string.strip('"')

                else:
                        string = string.strip("'")

                return self.unescape(string, _entities)

        # SPLIT FUNCTIONS

        @classmethod
        def splitdtd(self, dtdstring):
                """
                splitdtd(dtdstring) -> dtdstring

                TODO: to be implemented
                """

                return dtdstring

        @classmethod
        def splitcdata(self, cdatastring):
                """
                splitcdata(cdatastring) -> string

                Remove the XML CDATA encapsulation.
                """

                return cdatastring.lstrip('<![CDATA[').rstrip(']]>')

        @classmethod
        def splitcomment(self, commentstring):
                """
                splitcomment(commentstring) -> string

                Remove the XML Comment encapsulation.
                """

                return commentstring.lstrip('<!--').rstrip('-->').strip()

        @classmethod
        def splitpi(self, pistring):
                """
                splitpi(pistring) -> target, content

                Remove the XML PI encapsulation.
                """

                pistring = pistring.lstrip('<?').rstrip('?>').strip()

                try:
                        space = pistring.index(' ')

                except:
                        space = 0

                return pistring[:space], pistring[space:].strip()

        @classmethod
        def splitattributes(self, attributestring):
                """
                splitattributes(attributestring) -> dict

                Remove the XML Attribute encapsulation and return a dictionary 
that
                maps attribute names to their coresponding values.
                """

                string = attributestring.strip()

                if not string:
                        return {}

                attributedict = {}

                while True:
                        index = string.index('=')
                        name = string[:index].strip()
                        rest = string[index + 1:].strip()

                        if rest.startswith('"'):
                                end = rest[1:].index('"')

                        else:
                                end = rest[1:].index("'")

                        value = self.unquote(rest[:end + 2])
                        attributedict[name] = value

                        string = rest[end + 2:].strip()

                        if not string:
                                break

                return attributedict

        @classmethod
        def splitelement(self, elementstring):
                """
                splitelement(elementstring) -> qname, attributestring

                Remove the XML Element encapsulation and split to a tuple that 
contains
                the element name and the attributestring.
                """

                element = elementstring.lstrip('<').rstrip('>')

                try:
                        space = element.index(' ')

                except:
                        space = len(element)

                qname = element[:space].strip('/').strip()
                attributestring = element[space:].rstrip('/').strip()

                return qname, attributestring

        @classmethod
        def splitstring(self, string):
                """
                splitstring(string) -> generator

                Split string to XML Nodes.
                """

                if not string:
                        raise StopIteration

                while True:
                        try:
                                index = string.index('<')

                        except:
                                index = len(string)

                        if string[:index]:
                                end = index

                        elif string.startswith('<![CDATA['):
                                end = string.index(']]>') + 3

                        elif string.startswith('<?'):
                                end = string.index('?>') + 2

                        elif string.startswith('<!DOCTYPE'):
                                end = string.index(']>') + 2

                        elif string.startswith('<!--'):
                                end = string.index('-->') + 3

                        else:
                                end = string.index('>') + 1

                        yield string[:end]
                        string = string[end:]

                        if not string:
                                break

        @classmethod
        def splitstream(self, stream):
                """
                splitstream(stream) -> generator

                Split stream to XML Nodes.
                
                TODO: implement stream parser instead of calling splitstring 
method
                """

                return self.splitstring(stream.read())

        @classmethod
        def splitfile(self, filepath):
                """
                splitfile(filepath) -> generator

                Split file to XML Nodes.
                """

                file = open(filepath)
                generator = self.splitstream(file)
                file.close()

                return generator

        @classmethod
        def parsenodes(self, nodes, handler):
                """
                parsenodes(nodes, handler) -> None

                Dispatch XML Nodes to their coresponding event handler.
                """

                for node in nodes:
                        if node.startswith('<![CDATA['):
                                handler.cdata(self.splitcdata(node))

                        elif node.startswith('<?'):
                                handler.pi(*self.splitpi(node))

                        elif node.startswith('<!DOCTYPE'):
                                handler.dtd(*self.splitdtd(node))

                        elif node.startswith('<!--'):
                                handler.comment(self.splitcomment(node))

                        elif node.startswith('</'):
                                qname, attributes = self.splitelement(node)
                                handler.endelement(qname)

                        elif node.endswith('/>'):
                                qname, attributes = self.splitelement(node)
                                handler.beginelement(qname, 
self.splitattributes(attributes))
                                handler.endelement(qname)

                        elif node.startswith('<'):
                                qname, attributes = self.splitelement(node)
                                handler.beginelement(qname, 
self.splitattributes(attributes))

                        else:
                                handler.text(node)

        @classmethod
        def parsestream(self, stream, handler):
                """
                parsestream(stream, handler) -> None

                Dispatch XML Nodes from stream to their coresponding event 
handler.
                """

                self.parsenodes(self.splitstream(stream), handler)

        @classmethod
        def parsefile(self, filepath, handler):
                """
                parsefile(filepath, handler) -> None

                Dispatch XML Nodes from file to their coresponding event 
handler.
                """

                self.parsenodes(self.splitfile(filepath), handler)

        @classmethod
        def parsestring(self, string, handler):
                """
                parsestring(string, handler) -> None

                Dispatch XML Nodes from string to their coresponding event 
handler.
                """

                self.parsenodes(self.splitstring(string), handler)

# XML PARSER WITH NAMESPACE SUPPORT

class ParserNS(Parser):
        """
        ParserNS extends Parser by adding namespace support.
        """

        @classmethod
        def splitqname(self, qname):
                """
                splitqname(qname) -> prefix, localName

                Split qualified name to prefix, localName tuple.
                """

                try:
                        index = qname.index(':')

                except:
                        return '', qname

                return qname[:index], qname[index + 1:]

        @classmethod
        def splituname(self, uname):
                """
                splituname(uname) -> namespace, localName

                Split universal name to namespace, localName tuple.
                """

                try:
                        index = uname.index('}')

                        if not uname.startswith('{'):
                                raise

                except:
                        return '', uname

                return uname[1:index], uname[index + 1:]

        @classmethod
        def splitnamespaces(self, attributes):
                """
                splitnamespaces(attributes) -> namespaces, attributes

                Separate namespace declarations from the attribute dictionary.
                """

                namespacedict = {}
                attributedict = {}

                for name, value in attributes.iteritems():
                        prefix, _name = self.splitqname(name)

                        if prefix == 'xmlns':
                                namespacedict[_name] = value

                        elif prefix == '' and _name == 'xmlns':
                                namespacedict[''] = value

                        else:
                                attributedict[name] = value

                return namespacedict, attributedict

        @classmethod
        def findnamespace(self, prefix, nslevels):
                """
                findnamespace(prefix, nslevels) -> namespace

                Find namespace by prefix. This functions is a bit misleading. 
The
                nslevels dictionary contains level to namespaces dictionary 
mappings.
                The level represents the level at which a namespace declration 
is
                found.
                """

                for index in reversed(nslevels.keys()):
                        try:
                                return nslevels[index][prefix]

                        except:
                                pass

                return ''

        @classmethod
        def rebuildattributes(self, attributes, nslevels):
                """
                rebuildattributes(attributes, nslevels) -> qualified_attributes

                Rebuild attributes according to nslevels. The nslevels 
dictionary is
                used by the findnamespace method to find the coresponding 
namespace for
                each attribute.
                """

                _attributes = {}

                for name, value in attributes.iteritems():
                        prefix, name = self.splitqname(name)
                        namespace = self.findnamespace(prefix, nslevels)
                        _attributes[namespace, prefix, name] = value

                return _attributes

        @classmethod
        def parsenodes(self, nodes, handler):
                """
                parsenodes(nodes, handler) -> None

                Dispatch XML Nodes to their coresponding event handler.
                """

                namespaces = {}
                count = 0

                for node in nodes:
                        if node.startswith('<![CDATA['):
                                handler.cdata(self.splitcdata(node))

                        elif node.startswith('<?'):
                                handler.pi(*self.splitpi(node))

                        elif node.startswith('<!DOCTYPE'):
                                handler.dtd(self.splitdtd(node))

                        elif node.startswith('<!--'):
                                handler.comment(self.splitcomment(node))

                        elif node.startswith('</'):
                                count -= 1

                                qname, attributes = self.splitelement(node)
                                prefix, name = self.splitqname(qname)
                                namespace = self.findnamespace(prefix, 
namespaces)

                                if namespaces.has_key(count):
                                        del namespaces[count]

                                handler.endelement((name, prefix, namespace))

                        elif node.endswith('/>'):
                                qname, attributes = self.splitelement(node)
                                prefix, name = self.splitqname(qname)
                                attributes = self.splitattributes(attributes)
                                nsattributes, attributes = 
self.splitnamespaces(attributes)
                                attributes = self.rebuildattributes(attributes, 
namespaces)

                                if nsattributes:
                                        namespaces[count] = nsattributes

                                namespace = self.findnamespace(prefix, 
namespaces)

                                if namespaces.has_key(count):
                                        del namespaces[count]

                                handler.beginelement((name, prefix, namespace), 
attributes)
                                handler.endelement((name, prefix, namespace))

                        elif node.startswith('<'):
                                qname, attributes = self.splitelement(node)
                                prefix, name = self.splitqname(qname)
                                attributes = self.splitattributes(attributes)
                                nsattributes, attributes = 
self.splitnamespaces(attributes)
                                attributes = self.rebuildattributes(attributes, 
namespaces)

                                if nsattributes:
                                        namespaces[count] = nsattributes

                                namespace = self.findnamespace(prefix, 
namespaces)
                                handler.beginelement((name, prefix, namespace), 
attributes)

                                count += 1

                        else:
                                handler.text(node)

# CONTENT HANDLER

class Handler(object):
        """
        Handle XML Events.
        """

        def beginelement(self, qname, attributes):
                pass

        def endelement(self, qname):
                pass

        def dtd(self, content):
                pass

        def text(self, content):
                pass

        def cdata(self, content):
                pass

        def comment(self, content):
                pass

        def pi(self, target, content):
                pass

# PEX HANDLER, PARSER AND COMPOSER

class PEXHandler(Handler):
        """
        Build PEX from ParserNS.
        """

        def __init__(self, normalize = True):
                self.nodes = []
                self.prefixes = {}
                self.normalize = normalize
                self.elementque = [self]

        def beginelement(self, qname, attributes):
                name, prefix, namespace = qname
                self.prefixes[prefix] = namespace

                element = Element(name, namespace, prefix)

                for (namespace, prefix, name), value in attributes.iteritems():
                        element.attributes.append(Attribute(
                                name, value, namespace, prefix))

                self.elementque[-1].nodes.append(element)
                self.elementque.append(element)

        def endelement(self, qname):
                name, prefix, namespace = qname
                self.prefixes[prefix] = namespace

                self.elementque.pop()

        def dtd(self, content):
                self.elementque[-1].nodes.append(DTD(content))

        def cdata(self, content):
                self.elementque[-1].nodes.append(CDATA(content))

        def comment(self, content):
                self.elementque[-1].nodes.append(Comment(content))

        def pi(self, target, content):
                self.elementque[-1].nodes.append(PI(target, content))

        def text(self, content):
                if self.normalize:
                        content = content.strip()

                        if content:
                                self.elementque[-1].nodes.append(Text(content))

                else:
                        self.elementque[-1].nodes.append(Text(content))

class PEXParser(object):
        """
        Build PEX from PEXHandler and ParserNS.
        """

        @classmethod
        def parsestring(self, string, normalize = True):
                """
                parsestring(string, normalize = True) -> []

                Parse string and return nodes as list.
                """

                handler = PEXHandler(normalize)
                ParserNS.parsestring(string, handler)
                return handler.nodes

        @classmethod
        def parsestream(self, stream, normalize = True):
                """
                parsestream(stream, normalize = True) -> []

                Parse stream and return nodes as list.
                """

                handler = PEXHandler(normalize)
                ParserNS.parsestream(stream, handler)
                return handler.nodes

        @classmethod
        def parsefile(self, filepath, normalize = True):
                """
                parsefile(filepath, normalize = True) -> []

                Parse file and return nodes as list.
                """

                handler = PEXHandler(normalize)
                ParserNS.parsefile(filepath, handler)
                return handler.nodes

class PEXComposer(object):
        """
        Compose XML from PEX.
        """

        @classmethod
        def findprefix(self, namespace, namespaces):
                """
                findprefix(namespace, namespaces) -> prefix

                Find prefix from namespace in namespaces. Otherwise, return 
None.
                """

                for key, value in namespaces.iteritems():
                        if value == namespace:
                                return key

        @classmethod
        def findnamespace(self, prefix, namespaces):
                """
                findnamespace(prefix, namespaces) -> namespace

                Find namespace from prefix in namespaces. Otherwise, return 
None.
                """

                try:
                        return namespaces[prefix]

                except:
                        pass

        @classmethod
        def addnamespace(self, namespace, prefix, namespaces):
                """
                addnamespace(namespace, prefix, namespaces) -> None

                Add prefix to namespace mapping in namespaces as such all 
prefix names
                are resolved automatically. 
                """

                if namespaces.has_key(prefix):
                        if namespaces[prefix] != namespace:
                                index = 0
                                prefix = 'ns0'

                                while namespaces.has_key(prefix):
                                        index = index + 1
                                        prefix = 'ns' + str(index)

                                namespaces[prefix] = namespace

                else:
                        _prefix = self.findprefix(namespace, namespaces)

                        if _prefix is None:
                                namespaces[prefix] = namespace

        @classmethod
        def extractnamespaces(self, list, namespaces = {}):
                """
                extractnamespaces(list) -> {}

                Extract namespaces from nodes and return prefix to namespaces 
mappins
                in a dictionary. list must contain Element and Attributes only. 
The
                optional namespaces parameter supplies base namespaces.
                """

                _namespaces = {}
                _namespaces.update(namespaces)

                for item in list:
                        if not item.namespace:
                                continue

                        prefix = item.prefix or 'ns0'
                        self.addnamespace(item.namespace, prefix, _namespaces)

                return _namespaces

        @classmethod
        def exportnode(self, node, stream, namespaces = {}):
                """
                exportnode(node, stream, namespaces = {}) -> None

                Export node into stream. The namespaces parameter will be 
modified.
                Exported elements does not contain xml declrations.
                """

                if isinstance(node, PI):
                        stream.write('<?%s %s ?>' % (node.target or '', 
node.content))

                elif isinstance(node, DTD):
                        stream.write(node.content)

                elif isinstance(node, CDATA):
                        stream.write('<![CDATA['+ node +']>')

                elif isinstance(node, Comment):
                        stream.write('<!-- ' + node + ' -->')

                elif isinstance(node, (Text, str, unicode)):
                        stream.write(node)

                elif isinstance(node, Element):
                        pass

                else:
                        raise ValueError, 'TODO: add message here'

        @classmethod
        def exportnodens(self, node, stream, namespaces = {}):
                """
                exportnodens(node, stream, namespaces = {} -> None

                Export node into stream. The namespaces parameter will be 
modified.
                Exported element contain namespace declarations.
                """

                if not isinstance(node, Element):
                        self.exportnode(node, stream, namespaces)

                else:
                        namespaces = self.extractnamespaces(
                                [node] + node.attributes,
                                namespaces)

                        buff = cStringIO.StringIO()

                        for _node in node.nodes:
                                self.exportnode(_node, buff, namespaces)

                        attributes = ''

                        for attribute in node.attributes:
                                attributes = '%s %s=%s' % (
                                        attributes,
                                        attribute.name,
                                        ParserNS.quote(attribute.value))

                        for prefix, namespace in namespaces.iteritems():
                                attributes = '%s %s=%s' % (
                                        attributes,
                                        'xmlns:' + prefix,
                                        namespace)

                        prefix = self.findprefix(node.namespace, namespaces)
                        name = '%s:%s' % (prefix, node.name)

                        if not node.nodes:
                                stream.write('<%s%s/>' % (name, attributes))

                        else:
                                stream.write('<%s%s>' % (name, attributes))
                                stream.write(buff.getvalue())
                                stream.write('<%s>' % name)

        @classmethod
        def composestream(self, pex, stream, encoding = 'utf-8', namespaces = 
{}):
                """
                composestream(pex, stream, encoding = 'utf-8', namespaces = {}) 
-> None

                Compose XML document from pex and write to stream. pex is either
                Element or list.
                """

                class encapsulate(object):
                        def __init__(self, stream): self.stream = stream
                        def write(self, string): 
self.stream.write(string.encode(encoding))

                stream = encapsulate(stream)
                stream.write('<?xml version="1.0" encoding="%s"?>\n' % encoding)

                if isinstance(pex, list):
                        for node in pex:
                                if isinstance(node, PI) and node.target == 
'xml':
                                        continue

                                self.exportnodens(node, stream, namespaces)

                else:
                        self.exportnodens(pex, stream, namespaces)

        @classmethod
        def composestring(self, pex, encoding = 'utf-8', namespaces = {}):
                """
                composestring(pex, encoding = 'utf-8', namespaces = {}) -> 
string

                Compose XML document from pex and return string. pex is either 
Element
                or list.
                """

                stream = cStringIO.StringIO()
                self.composestream(pex, stream, encoding, namespaces)
                return stream.getvalue()

        @classmethod
        def composefile(self, pex, filepath, encoding = 'utf-8', namespaces = 
{}):
                """
                composefile(pex, filepath, encoding = 'utf-8', namespaces = {}) 
-> None

                Compose XML document from pex and write to file. pex is either 
Element
                or list.
                """

                file = open(filepath, 'w')
                self.composestream(pex, file, encoding, namespaces)
                file.close()

# PEX TYPES

class Text(unicode):
        """
        XML Text node
        """

class CDATA(unicode):
        """
        XML CDATA node
        """

class Comment(unicode):
        """
        XML Comment node
        """

class PI(object):
        """
        XML ProcessInstruction node
        """

        def __init__(self, target = '', content = ''):
                self.target = target
                self.content = content

class DTD(object):
        """
        XML DTD node

        NOTE: not implemented
        """

        def __init__(self, content):
                self.content = content

class Attribute(object):
        """
        XML Attribute
        """

        def __init__(self, name, value = '', namespace = '', prefix = ''):
                self.name = name
                self.value = value
                self.namespace = namespace
                self.prefix = prefix

class Element(object):
        """
        XML Element
        """

        def __init__(self, name, namespace = '', prefix = ''):
                self.name = name
                self.namespace = namespace
                self.prefix = prefix

                self.nodes = []
                self.attributes = []

# PEX HELPERS

class Composer(PEXComposer):
        """
        Compose XML from Binding
        """

        def __init__(self, binding, encoding = 'utf-8', namespaces = {}):
                self.encoding = encoding
                self.namespaces = namespaces

                if isinstance(binding, Binding):
                        if binding.xml_name == '__binding__':
                                self.element = binding.xml_nodes

                        else:
                                self.element = binding.xml_element

                else:
                        self.element = binding

        def __call__(self, encoding = None, namespaces = None, stream = None,
                     file = None):

                if encoding is None:
                        encoding = self.encoding

                if namespaces is None:
                        namespaces = self.namespaces
                
                if stream is not None:
                        self.composestream(self.element, stream, encoding, 
namespaces)

                elif file is not None:
                        self.composefile(self.element, file, encoding, 
namespaces)

                else:
                        return self.composestring(self.element, encoding, 
namespaces)

        def __str__(self):
                return self.composestring(self.element, self.encoding, 
self.namespaces)

class Binding(object):
        """
        XML to Python object Binding
        """

        def __init__(self, element, origin = None):
                self.xml_element = element
                self.xml_origin = origin
                self.xml = Composer(element)

        def __getattr__(self, name):
                if not name.startswith('xml'):
                        for attribute in self.xml_element.attributes:
                                if attribute.name == name:
                                        return attribute.value

                        for node in self.xml_element.nodes:
                                if isinstance(node, Element) and node.name == 
name:
                                        return Binding(node, self.xml_element)

                else:
                        if name not in ('xml_element', 'xml_origin'):
                                return getattr(self.xml_element, name[4:])

                raise AttributeError, 'TODO: add message here'

        def __setattr__(self, name, value):
                if not name.startswith('xml'):
                        for attribute in self.xml_element.attributes:
                                if attribute.name == name:
                                        attribute.value = value
                                        return

                        for node in self.xml_element.nodes:
                                if isinstance(node, Element) and node.name == 
name:
                                        return self.__setelement_(node, value)

                        self.xml_element.attributes.append(Attribute(
                                name = name,
                                value = value))

                        return

                object.__setattr__(self, name, value)

        def __delattr__(self, name):
                if not name.startswith('xml'):
                        for index, attribute in 
enumerate(self.xml_element.attributes):
                                if attribute.name == name:
                                        del self.xml_element.attributes[index]
                                        return

                        for index, node in enumerate(self.xml_element.nodes):
                                if isinstance(node, Element) and node.name == 
name:
                                        del self.xml_elements.nodes[index]
                                        return

                raise AttributeError, 'TODO: add message here'

        def __getitem__(self, key):
                if isinstance(key, slice):
                        # TODO: support for slices
                        pass

                elif isinstance(key, int):
                        if self.xml_origin is None:
                                raise RuntimeError, 'TODO: add message here'

                        if key >= 0:
                                nodes = lambda: self.xml_origin.nodes

                        else:
                                nodes = lambda: reversed(self.xml_origin.nodes)
                                key = key * -1 - 1

                        for node in nodes():
                                if isinstance(node, Element) \
                                and node.name == self.xml_element.name:
                                        if key == 0:
                                                return Binding(node)

                                        key = key - 1

                        raise IndexError, 'TODO: add message here'

                elif isinstance(key, (str, unicode)):
                        matches = self.__makematch_(key)

                        if key.startswith('@'):
                                for attribute in self.xml_element.attributes:
                                        if matches(attribute):
                                                return attribute.value

                        else:
                                for node in self.xml_element.nodes:
                                        if matches(node):
                                                return Binding(node, 
self.xml_element)

                raise KeyError, 'TODO: add message here'

        def __setitem__(self, key, value):
                if isinstance(key, slice):
                        # TODO: support for slices
                        pass

                elif isinstance(key, int):
                        if self.xml_origin is None:
                                raise RuntimeError, 'TODO: add message here'

                        if key >= 0:
                                nodes = lambda: self.xml_origin.nodes

                        else:
                                nodes = lambda: reversed(self.xml_origin.nodes)
                                key = key * -1 - 1

                        for node in nodes():
                                if isinstance(node, Element) \
                                and node.name == self.xml_element.name:
                                        if key == 0:
                                                return self.__setelement_(node, 
value)

                                        key = key - 1

                        raise IndexError, 'TODO: add message here'

                elif isinstance(key, (str, unicode)):
                        matches = self.__makematch_(key)

                        if key.startswith('@'):
                                for attribute in self.xml_element.attributes:
                                        if matches(attribute):
                                                attribute.value = value
                                                return

                        else:
                                for node in self.xml_element.nodes:
                                        if matches(node):
                                                return self.__setelement_(node, 
value)

                raise KeyError, 'TODO: add message here'

        def __delitem__(self, key):
                if isinstance(key, slice):
                        # TODO: support for slices
                        pass

                elif isinstance(key, int):
                        if self.xml_origin is None:
                                raise RuntimeError, 'TODO: add message here'

                        if key >= 0:
                                nodes = lambda: self.xml_origin.nodes

                        else:
                                nodes = lambda: reversed(self.xml_origin.nodes)
                                key = key * -1 - 1

                        for index, node in enumerate(nodes()):
                                if isinstance(node, Element) \
                                and node.name == self.xml_element.name:
                                        if key == 0:
                                                del self.xml_origin.nodes[index]
                                                return

                                        key = key - 1

                        raise IndexError, 'TODO: add message here'

                elif isinstance(key, (str, unicode)):
                        matches = self.__makematch_(key)

                        if key.startswith('@'):
                                for index, attribute in 
enumerate(self.xml_element.attributes):
                                        if matches(attribute):
                                                del 
self.xml_element.attributes[index]
                                                return

                        else:
                                for index, node in 
enumerate(self.xml_element.nodes):
                                        if matches(node):
                                                del 
self.xml_element.nodes[index]
                                                return

                raise KeyError, 'TODO: add message here'

        def __len__(self):
                if self.xml_origin is None:
                        raise RuntimeError, 'TODO: add message here'

                len = 0

                for node in self.xml_origin.nodes:
                        if isinstance(node, Element) \
                        and node.name == self.xml_element.name:
                                len = len + 1

                return len

        def __iter__(self):
                if self.xml_origin is None:
                        raise RuntimeError, 'TODO: add message here'

                def iterator():
                        for node in self.xml_origin.nodes:
                                if isinstance(node, Element) \
                                and node.name == self.xml_element.name:
                                        yield Binding(node)

                return iterator()

        def __repr__(self):
                return PEXComposer.composestring(self.xml_element.nodes)

        def __setelement_(self, element, value):
                """
                __setelement_(element, value) -> None

                Set element content to value. value is string, Binding or 
another
                Element.
                """

                if isinstance(value, (str, unicode)):
                        element.nodes = PEXParser.parsestring(value)

                elif isinstance(value, Binding):
                        node.name = value.xml_name
                        node.namespace = value.xml_namespace
                        node.prefix = value.xml_prefix
                        node.attributes = value.xml_attributes
                        node.nodes = value.xml_nodes

                elif isinstance(value, Element):
                        node.name = value.name
                        node.namespace = value.namespace
                        node.prefix = value.prefix
                        node.attributes = value.attributes
                        node.nodes = value.nodes

                else:
                        raise ValueError, 'TODO: add message here'

        @classmethod
        def fromstring(self, string, normalize = True):
                """
                fromstring(string, normalize = True) -> Binding

                Parse string and return Binding.
                """

                element = Element('__binding__')
                element.nodes = PEXParser.parsestring(string, normalize)
                return Binding(element)

        @classmethod
        def fromstream(self, stream, normalize = True):
                """
                fromstream(stream, normalize = True) -> Binding

                Parse stream and return Binding.
                """

                element = Element('__binding__')
                element.nodes = PEXParser.parsestream(stream, normalize)
                return Binding(element)

        @classmethod
        def fromfile(self, filepath, normalize = True):
                """
                fromfile(filepath, normalize = True) -> Binding

                Parse file and return Binding.
                """

                element = Element('__binding__')
                element.nodes = PEXParser.parsefile(filepath, normalize)
                return Binding(element)

_______________________________________________
XML-SIG maillist  -  XML-SIG@python.org
http://mail.python.org/mailman/listinfo/xml-sig

Reply via email to