[XML-SIG] Interface for XSD datatypes

Andrew Kuchling akuchlin@mems-exchange.org
Thu, 14 Feb 2002 10:21:04 -0500


RELAX NG requires support for the primitive datatypes defined in part
2 of the XML Schema standard.  Support for datatypes would be useful
outside of the RELAX NG processor, if, for example, someone wanted to
implement XML Schema in Python or if other standards adopt the XML
Schema datatypes.  Therefore, I'd like to get comments on a proposed
interface for datatypes.

#
# Datatype interfaces
#

class DatatypeValueError(Exception):
    """
    Exception raised when a supplied string does not represent
    a legal value for a datatype.
    
    Instance attributes:
      message : string
        Message explaining what's wrong with the string
    """

class DatatypeURIError(Exception):
    """
    Exception raised when there's no datatype library corresponding
    to a given URI.
    """

class DatatypeLibCollection:
    """
    Holder of a bunch of datatype libraries.
    """
    
    def register (self, library):
        """register(library : DatatypeLibrary)
        Add 'library' to the list of libraries available in this collection.
        """

    def has_uri (self, uri):
        """has_uri(uri:string) : boolean
        Returns true if there's a datatype library registered for the given
        URI.
        """

    def has_type (self, (uri, type)):
        """has_uri((uri:string,type:string)) : boolean
        Returns true if the specified datatype exists.
        """
        
    def check (self, (uri,type), params, value):
        """check((uri:string,type:string),
                 params: {string : string},
                 value : string) : boolean
        Returns true if the string 'value' represents a legal
        value for the datatype selected by the (uri,type) pair,
        taking the additional parameters 'params' into account.
        If this method returns false, it might mean either
        that the uri isn't for any registered library, or
        that the library is OK and the value is wrong.
        XXX should this return an explanatory message, or should
        there be a third function (explain()?)
        """

        try:
            value = self.evaluate((uri,type), params, value)
        except (DatatypeValueError, DatatypeURIError):
            return 0
        else:
            return 1
            

    def evaluate (self, (uri,type), params, value):
        """evaluate((uri:string,type:string),
                    params: {string : string},
                    value : string) : any

        Evaluate the string 'value' as a value of the datatype
        selected by the (uri,type) pair, taking the additional
        parameters 'params' into account.  Raises DatatypeValueError
        if the value is illegal; raises DatatypeURIError if there's
        no library registered for that URI.
        """        


class DatatypeLibrary:
    """
    Instance attributes:
      uri : string
        Namespace URI for this collection of data types
    """

    def evaluate(self, type, params, value):
        """evaluate(type:string,
                    params: {string : string},
                    value : string) : any

        Evaluate the string 'value' as a value of the datatype
        selected by the name 'type', taking the additional parameters
        'params' into account.  Raises DatatypeValueError with an
        explanatory message if the value is illegal.
        """

    def has_type (self, type):
        """has_type(type:string) : boolean
        Returns true if the library supports a type with the given name.
        """

    def is_type_legal (self, type, params):
        """is_type_legal(type:string, params:{string:string}) : boolean
        Returns true if the type and corresponding parameters are legal.
        """
    
        
def get_xsd_library ():
    """get_xsd_library(): DatatypeLibrary
    Return the library for the XML Schema standard's primitive
    datatypes.
    """
    
I envision the RELAX NG interface ultimately looking like this:
schema = relaxng.parse(...) # Get a relaxng.Schema object with a
                            # .datatypecoll attribute.
                            # It will initially have just the
                            # XML Schema library registered.

# Add a custom type library
schema.datatypecoll.register(myTypeLibrary)
# Check a document against the schema
print schema.is_valid(...)

The code will live in sandbox/datatype for now.  Should it go in the
XML tree eventually, or be a separate library?  If the former, where
should it go?  xml.schema.datatype, xml.datatype, ... ?

--amk                                                  (www.amk.ca)
My customers consider it a marketable skill that I a) think for myself
b) share my thoughts with them.
    -- Paul Prescod, 2 Nov 1998