"""
A SAX driver for xmlproc with validation and DTD information.
"""

version="0.90"

from xml.sax import saxlib,saxutils
from xml.parsers.xmlproc import xmlval
from xml.sax.drivers.drv_xmlproc import *

import types

# --- SAX_XPValParser

class SAX_XPValParser(SAX_XPParser):

    def __init__(self):
        SAX_XPParser.__init__(self)
    
    def parse(self,sysID):
	self.parser=self.__create_parser()
	self.parser.set_application(self)
        self.parser.set_dtd_listener(self)
	self.parser.set_error_handler(self)
        self.dtd=self.parser.get_dtd()
	self.doc_handler.setDocumentLocator(self)
	self.parser.parse_resource(sysID)
	
    def __create_parser(self):
	return xmlval.XMLValidator()

    def handle_start_tag(self, name, attrs):
        try:
            self.doc_handler.startElement(name,
                                          XPAttributes(attrs,\
                                                       self.dtd.get_elem(name)))
        except KeyError,e:
            self.doc_handler.startElement(name,XPAttributes(attrs,None))
            
    # --- EXPERIMENTAL PYTHON SAX EXTENSIONS:

    def get_parser_name(self):
        return "xmlproc_val"

    def get_driver_version(self):
        return version
    
    def is_validating(self):
        return 1
        
# --- XPAttributes

class XPAttributes(saxutils.AttributeMap):

    def __init__(self,map,elemdecl):
        saxutils.AttributeMap.__init__(self,map)        
        self.elemdecl=elemdecl

        if elemdecl==None:
            self.getType=self.getTypeStatic

    def getTypeStatic(self,i):
        return "CDATA"        # Used for undeclared elements
        
    def getType(self, i):
	if type(i)==types.IntType:
            try:
                i=self.map.keys()[i]
            except KeyError,e:
                return "CDATA"

        try:
            return self.elemdecl.get_attr(i).get_type()
        except KeyError,e:
            return "CDATA"

# --- Global functions

def create_parser():
    return SAX_XPValParser()
    
