[Zope-Checkins] CVS: Zope3/lib/python/Zope/Configuration - xmlconfig.py:1.1.2.1

Jim Fulton jim@zope.com
Mon, 19 Nov 2001 17:01:19 -0500


Update of /cvs-repository/Zope3/lib/python/Zope/Configuration
In directory cvs.zope.org:/tmp/cvs-serv9309

Added Files:
      Tag: Zope-3x-branch
	xmlconfig.py 
Log Message:
Added xml config file parser

=== Added File Zope3/lib/python/Zope/Configuration/xmlconfig.py ===
from xml.sax import make_parser
from xml.sax.handler import ContentHandler, feature_namespaces
from meta import execute
from keyword import iskeyword

class ZopeXMLConfigurationError(Exception):
    "Zope XML Configuration error"

    def __init__(self, locator, mess):
        self.lno=locator.getLineNumber()
        self.cno=locator.getColumnNumber()
        self.mess=mess

    def __str__(self):
        return "%s at line %s column %s" % (self.mess, self.lno, self.cno)

class ConfigurationHandler(ContentHandler):

    __top_name = 'http://namespaces.zope.org/zope', 'zopeConfigure' 

    def __init__(self):
        self.__stack=[]

    def setDocumentLocator(self, locator):
        self.__locator=locator

    def startElementNS(self, name, qname, attrs):
        stack=self.__stack
        if not stack:
            if name != self.__top_name:
                raise ZopeXMLConfigurationError(
                    self.__locator, "Invalid top element: %s" % name)
            stack.append(None)
            return

        kw={}
        for (ns, aname), value in attrs.items():
            if ns is None:
                aname=str(aname)
                if iskeyword(aname): aname += '_'
                kw[aname]=value

        if len(stack) == 1:
            stack.append(execute(*name, **kw))
            self.__ns = name[0]
        else:
            if self.__ns != name[0]:
                raise ZopeXMLConfigurationError(self.__locator,
                                                'Namespace missmatch')
            ob = self.__stack[-1]
            if ob is None:
                raise ZopeXMLConfigurationError(self.__locator,
                                                'Invalid sub-directive')
            stack.append(getattr(ob, name[1])(**kw))

    def endElementNS(self, name, qname):
        ob = self.__stack.pop()
        if ob is not None: ob()


def xmlconfig(file):
    parser=make_parser()
    parser.setContentHandler(ConfigurationHandler())
    parser.setFeature(feature_namespaces, 1)
    parser.parse(file)