import popen2
import os
import string
import sys

class NotImplemented(Exception):
    pass

class Invalid(Exception):
    pass

class Check:
    """ Checks a XML document against a RelaxNG schema """

    def __init__(self, schemaURI, xmlform=False):
        """ The schemaURI is provided in Compact Form. Otherwise, you
        need to set xmlform to True and the trang converter must be
        available. TODO: autodetect the syntax. """
        if xmlform:
            raise NotImplemented("XML syntax for RelaxNG not yet supported")
        self.schema = schemaURI

    def check(self, what):
        """ Do the actual test. Return nothing if everything is well
        and raises Invalid otherwise. """
        tmpname = os.environ['HOME'] + "/.RelaxNGCheck.tmp.xml"
        tmp = open(tmpname, "w")
        tmp.write("%s\n" % what)
        tmp.close()
        (scheme, schema) = string.split(self.schema, ':')
        # TODO: handle http URI
        rnv = popen2.Popen3("rnv -q %s %s" % (schema, tmpname), capturestderr=True)
        rnv.tochild.write(what)
        result = rnv.fromchild.read()
        errors = rnv.childerr.read()
        if errors != "":
            raise Invalid(errors)

if __name__ == '__main__':
    checker = Check("file:schema-reply.rnc", False)
    checker.check(open("example-reply.xml").read())
    try:
        checker.check("""
     <domain>
            <holder>FOO-NIC</holder>
            <created>2006-13-13</created>
            <creator>127.0.0.1</creator>
     </domain>""")
        sys.stderr.write("The invalid XML document was accepted :-(\n")
    except Invalid:
        pass
