1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-07-30 22:43:14 +03:00

Applied patch from Torkel Lyng to add Schemas support to the Python

* xmlschemas.c include/libxml/xmlschemas.h python/generator.py
  python/libxml.c python/libxml_wrap.h python/types.c
  python/tests/schema.py python/tests/Makefile.am: Applied patch
  from Torkel Lyng to add Schemas support to the Python bindings
  and extend the schemas error API, registered a new test.
* doc/* elfgcchack.h: rebuilt to regenerate the bindings
Daniel
This commit is contained in:
Daniel Veillard
2004-08-18 09:13:18 +00:00
parent c14c3892a2
commit 259f0dfa8b
91 changed files with 2706 additions and 1812 deletions

View File

@ -282,6 +282,9 @@ py_types = {
'xmlRelaxNGPtr': ('O', "relaxNgSchema", "xmlRelaxNGPtr", "xmlRelaxNGPtr"),
'xmlRelaxNGParserCtxtPtr': ('O', "relaxNgParserCtxt", "xmlRelaxNGParserCtxtPtr", "xmlRelaxNGParserCtxtPtr"),
'xmlRelaxNGValidCtxtPtr': ('O', "relaxNgValidCtxt", "xmlRelaxNGValidCtxtPtr", "xmlRelaxNGValidCtxtPtr"),
'xmlSchemaPtr': ('O', "Schema", "xmlSchemaPtr", "xmlSchemaPtr"),
'xmlSchemaParserCtxtPtr': ('O', "SchemaParserCtxt", "xmlSchemaParserCtxtPtr", "xmlSchemaParserCtxtPtr"),
'xmlSchemaValidCtxtPtr': ('O', "SchemaValidCtxt", "xmlSchemaValidCtxtPtr", "xmlSchemaValidCtxtPtr"),
}
py_return_types = {
@ -666,6 +669,9 @@ classes_type = {
'xmlRelaxNGPtr': ('._o', "relaxNgSchema(_obj=%s)", "relaxNgSchema"),
'xmlRelaxNGParserCtxtPtr': ('._o', "relaxNgParserCtxt(_obj=%s)", "relaxNgParserCtxt"),
'xmlRelaxNGValidCtxtPtr': ('._o', "relaxNgValidCtxt(_obj=%s)", "relaxNgValidCtxt"),
'xmlSchemaPtr': ("._o", "Schema(_obj=%s)", "Schema"),
'xmlSchemaParserCtxtPtr': ("._o", "SchemaParserCtxt(_obj=%s)", "SchemaParserCtxt"),
'xmlSchemaValidCtxtPtr': ("._o", "SchemaValidCtxt(_obj=%s)", "SchemaValidCtxt"),
}
converter_type = {
@ -699,6 +705,9 @@ classes_destructors = {
"relaxNgSchema": "xmlRelaxNGFree",
"relaxNgParserCtxt": "xmlRelaxNGFreeParserCtxt",
"relaxNgValidCtxt": "xmlRelaxNGFreeValidCtxt",
"Schema": "xmlSchemaFree",
"SchemaParserCtxt": "xmlSchemaFreeParserCtxt",
"SchemaValidCtxt": "xmlSchemaFreeValidCtxt",
}
functions_noexcept = {
@ -710,6 +719,7 @@ functions_noexcept = {
reference_keepers = {
"xmlTextReader": [('inputBuffer', 'input')],
"relaxNgValidCtxt": [('relaxNgSchema', 'schema')],
"SchemaValidCtxt": [('Schema', 'schema')],
}
function_classes = {}

View File

@ -2948,6 +2948,171 @@ libxml_xmlRelaxNGFreeValidCtxt(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
return(Py_None);
}
typedef struct
{
PyObject *warn;
PyObject *error;
PyObject *arg;
} xmlSchemaValidCtxtPyCtxt;
typedef xmlSchemaValidCtxtPyCtxt *xmlSchemaValidCtxtPyCtxtPtr;
static void
libxml_xmlSchemaValidityGenericErrorFuncHandler(void *ctx, char *str)
{
PyObject *list;
PyObject *result;
xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
printf("libxml_xmlSchemaValiditiyGenericErrorFuncHandler(%p, %s, ...) called\n", ctx, str);
#endif
pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
list = PyTuple_New(2);
PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
PyTuple_SetItem(list, 1, pyCtxt->arg);
Py_XINCREF(pyCtxt->arg);
result = PyEval_CallObject(pyCtxt->error, list);
if (result == NULL)
{
/* TODO: manage for the exception to be propagated... */
PyErr_Print();
}
Py_XDECREF(list);
Py_XDECREF(result);
}
static void
libxml_xmlSchemaValidityGenericWarningFuncHandler(void *ctx, char *str)
{
PyObject *list;
PyObject *result;
xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
#ifdef DEBUG_ERROR
printf("libxml_xmlSchemaValidityGenericWarningFuncHandler(%p, %s, ...) called\n", ctx, str);
#endif
pyCtxt = (xmlSchemaValidCtxtPyCtxtPtr) ctx;
list = PyTuple_New(2);
PyTuple_SetItem(list, 0, libxml_charPtrWrap(str));
PyTuple_SetItem(list, 1, pyCtxt->arg);
Py_XINCREF(pyCtxt->arg);
result = PyEval_CallObject(pyCtxt->warn, list);
if (result == NULL)
{
/* TODO: manage for the exception to be propagated... */
PyErr_Print();
}
Py_XDECREF(list);
Py_XDECREF(result);
}
static void
libxml_xmlSchemaValidityErrorFunc(void *ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
libxml_xmlSchemaValidityGenericErrorFuncHandler(ctx, libxml_buildMessage(msg, ap));
va_end(ap);
}
static void
libxml_xmlSchemaValidityWarningFunc(void *ctx, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
libxml_xmlSchemaValidityGenericWarningFuncHandler(ctx, libxml_buildMessage(msg, ap));
va_end(ap);
}
static PyObject *
libxml_xmlSchemaSetValidErrors(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
{
PyObject *py_retval;
PyObject *pyobj_error;
PyObject *pyobj_warn;
PyObject *pyobj_ctx;
PyObject *pyobj_arg = Py_None;
xmlSchemaValidCtxtPtr ctxt;
xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
if (!PyArg_ParseTuple
(args, (char *) "OOO|O:xmlSchemaSetValidErrors", &pyobj_ctx, &pyobj_error, &pyobj_warn, &pyobj_arg))
return (NULL);
#ifdef DEBUG_ERROR
printf("libxml_xmlSchemaSetValidErrors(%p, %p, %p) called\n", pyobj_ctx, pyobj_error, pyobj_warn);
#endif
ctxt = PySchemaValidCtxt_Get(pyobj_ctx);
if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == -1)
{
py_retval = libxml_intWrap(-1);
return(py_retval);
}
if (pyCtxt == NULL)
{
/* first time to set the error handlers */
pyCtxt = xmlMalloc(sizeof(xmlSchemaValidCtxtPyCtxt));
if (pyCtxt == NULL) {
py_retval = libxml_intWrap(-1);
return(py_retval);
}
memset(pyCtxt, 0, sizeof(xmlSchemaValidCtxtPyCtxt));
}
/* TODO: check warn and error is a function ! */
Py_XDECREF(pyCtxt->error);
Py_XINCREF(pyobj_error);
pyCtxt->error = pyobj_error;
Py_XDECREF(pyCtxt->warn);
Py_XINCREF(pyobj_warn);
pyCtxt->warn = pyobj_warn;
Py_XDECREF(pyCtxt->arg);
Py_XINCREF(pyobj_arg);
pyCtxt->arg = pyobj_arg;
xmlSchemaSetValidErrors(ctxt, &libxml_xmlSchemaValidityErrorFunc, &libxml_xmlSchemaValidityWarningFunc, pyCtxt);
py_retval = libxml_intWrap(1);
return(py_retval);
}
static PyObject *
libxml_xmlSchemaFreeValidCtxt(ATTRIBUTE_UNUSED PyObject * self, PyObject * args)
{
xmlSchemaValidCtxtPtr ctxt;
xmlSchemaValidCtxtPyCtxtPtr pyCtxt;
PyObject *pyobj_ctxt;
if (!PyArg_ParseTuple(args, (char *)"O:xmlSchemaFreeValidCtxt", &pyobj_ctxt))
return(NULL);
ctxt = (xmlSchemaValidCtxtPtr) PySchemaValidCtxt_Get(pyobj_ctxt);
if (xmlSchemaGetValidErrors(ctxt, NULL, NULL, (void **) &pyCtxt) == 0)
{
if (pyCtxt != NULL)
{
Py_XDECREF(pyCtxt->error);
Py_XDECREF(pyCtxt->warn);
Py_XDECREF(pyCtxt->arg);
xmlFree(pyCtxt);
}
}
xmlSchemaFreeValidCtxt(ctxt);
Py_INCREF(Py_None);
return(Py_None);
}
#endif
#ifdef LIBXML_C14N_ENABLED

View File

@ -219,6 +219,10 @@ readerForMemory()
# functions from module xmlregexp
regexpCompile()
# functions from module xmlschemas
schemaNewMemParserCtxt()
schemaNewParserCtxt()
# functions from module xmlschemastypes
schemaCleanupTypes()
schemaCollapseString()
@ -630,6 +634,10 @@ Class xmlDoc(xmlNode)
NewWalker()
readerWalker()
# functions from module xmlschemas
schemaNewDocParserCtxt()
schemaValidateDoc()
# functions from module xpath
xpathNewContext()
xpathOrderDocElems()
@ -781,6 +789,11 @@ Class relaxNgSchema()
# functions from module xmlreader
RelaxNGSetSchema()
Class Schema()
# functions from module xmlschemas
schemaDump()
schemaNewValidCtxt()
Class Error()
# accessors
code()
@ -1032,6 +1045,14 @@ Class outputBuffer(ioWriteWrapper)
# functions from module xmlIO
write()
writeString()
Class SchemaParserCtxt()
# functions from module xmlschemas
schemaParse()
Class SchemaValidCtxt()
# functions from module xmlschemas
schemaValidateDoc()
Class xmlTextReaderLocator()
# functions from module xmlreader

View File

@ -18,7 +18,10 @@
#include <libxml/xmlregexp.h>
#include <libxml/xmlautomata.h>
#include <libxml/xmlreader.h>
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/relaxng.h>
#include <libxml/xmlschemas.h>
#endif
/**
* ATTRIBUTE_UNUSED:
@ -165,6 +168,30 @@ typedef struct {
#define PyrelaxNgValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
(((PyrelaxNgValidCtxt_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlSchemaPtr obj;
} PySchema_Object;
#define PySchema_Get(v) (((v) == Py_None) ? NULL : \
(((PySchema_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlSchemaParserCtxtPtr obj;
} PySchemaParserCtxt_Object;
#define PySchemaParserCtxt_Get(v) (((v) == Py_None) ? NULL : \
(((PySchemaParserCtxt_Object *)(v))->obj))
typedef struct {
PyObject_HEAD
xmlSchemaValidCtxtPtr obj;
} PySchemaValidCtxt_Object;
#define PySchemaValidCtxt_Get(v) (((v) == Py_None) ? NULL : \
(((PySchemaValidCtxt_Object *)(v))->obj))
#endif /* LIBXML_SCHEMAS_ENABLED */
PyObject * libxml_intWrap(int val);
@ -201,5 +228,8 @@ xmlXPathObjectPtr libxml_xmlXPathObjectPtrConvert(PyObject * obj);
PyObject * libxml_xmlRelaxNGPtrWrap(xmlRelaxNGPtr ctxt);
PyObject * libxml_xmlRelaxNGParserCtxtPtrWrap(xmlRelaxNGParserCtxtPtr ctxt);
PyObject * libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid);
PyObject * libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt);
PyObject * libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt);
PyObject * libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid);
#endif /* LIBXML_SCHEMAS_ENABLED */
PyObject * libxml_xmlErrorPtrWrap(xmlErrorPtr error);

View File

@ -32,6 +32,7 @@ PYTESTS= \
ctxterror.py\
readererr.py\
relaxng.py \
schema.py \
thread2.py \
sync.py \
tstLastError.py \

52
python/tests/schema.py Executable file
View File

@ -0,0 +1,52 @@
#!/usr/bin/python -u
import libxml2
import sys
# Memory debug specific
libxml2.debugMemory(1)
schema="""<?xml version="1.0" encoding="iso-8859-1"?>
<schema xmlns = "http://www.w3.org/2001/XMLSchema">
<element name = "Customer">
<complexType>
<sequence>
<element name = "FirstName" type = "string" />
<element name = "MiddleInitial" type = "string" />
<element name = "LastName" type = "string" />
</sequence>
<attribute name = "customerID" type = "integer" />
</complexType>
</element>
</schema>"""
instance="""<?xml version="1.0" encoding="iso-8859-1"?>
<Customer customerID = "24332">
<FirstName>Raymond</FirstName>
<MiddleInitial>G</MiddleInitial>
<LastName>Bayliss</LastName>
</Customer>
"""
ctxt_parser = libxml2.schemaNewMemParserCtxt(schema, len(schema))
ctxt_schema = ctxt_parser.schemaParse()
ctxt_valid = ctxt_schema.schemaNewValidCtxt()
doc = libxml2.parseDoc(instance)
ret = doc.schemaValidateDoc(ctxt_valid)
if ret != 0:
print "error doing schema validation"
sys.exit(1)
doc.freeDoc()
del ctxt_parser
del ctxt_schema
del ctxt_valid
libxml2.schemaCleanupTypes()
# Memory debug specific
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print "OK"
else:
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
libxml2.dumpMemory()

View File

@ -640,6 +640,63 @@ libxml_xmlRelaxNGValidCtxtPtrWrap(xmlRelaxNGValidCtxtPtr valid)
(char *) "xmlRelaxNGValidCtxtPtr", NULL);
return (ret);
}
PyObject *
libxml_xmlSchemaPtrWrap(xmlSchemaPtr ctxt)
{
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlSchemaPtrWrap: ctxt = %p\n", ctxt);
#endif
if (ctxt == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
ret =
PyCObject_FromVoidPtrAndDesc((void *) ctxt,
(char *) "xmlSchemaPtr", NULL);
return (ret);
}
PyObject *
libxml_xmlSchemaParserCtxtPtrWrap(xmlSchemaParserCtxtPtr ctxt)
{
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlSchemaParserCtxtPtrWrap: ctxt = %p\n", ctxt);
#endif
if (ctxt == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
ret =
PyCObject_FromVoidPtrAndDesc((void *) ctxt,
(char *) "xmlSchemaParserCtxtPtr", NULL);
return (ret);
}
PyObject *
libxml_xmlSchemaValidCtxtPtrWrap(xmlSchemaValidCtxtPtr valid)
{
PyObject *ret;
#ifdef DEBUG
printf("libxml_xmlSchemaValidCtxtPtrWrap: valid = %p\n", valid);
#endif
if (valid == NULL) {
Py_INCREF(Py_None);
return (Py_None);
}
ret =
PyCObject_FromVoidPtrAndDesc((void *) valid,
(char *) "xmlSchemaValidCtxtPtr", NULL);
return (ret);
}
#endif /* LIBXML_SCHEMAS_ENABLED */
PyObject *