Re: [xml] Python bindings: per parser context error handlers



On Sun, Jan 12, 2003 at 04:37:22PM +0100, Stéphane Bidoul wrote:
Hi,

I'd really like to have an error handler specific
to a given parser context in the python bindings.

I dig a bit in the code and the list and could not find
how it could be done with the current python bindings.

If there is a way to do it, please discard this message... 
just give me a hint ;-).

If it's not possible, here is the approach I would propose.

As I understand it, the way to do that in C is
to specify a callback in ctx->sax->error and ctx->vctx.error.

  yes,

Thus, there would be a libxml2mod.xmlSetParserCtxtErrorHandler(ctxt,f)

  okay

that would look like this in C:

PyObject *
libxml_xmlSetParserCtxtErrorHandler(ATTRIBUTE_UNUSED PyObject *self, PyObject *args)
{
    PyObject *py_retval;
    xmlParserCtxtPtr ctxt;
    PyObject *pyobj_ctxt;
    PyObject *f;
    PyObject *arg;

    if (!PyArg_ParseTuple(args, (char *)"OOO:xmlSetParserCtxtErrorHandler", &pyobj_ctxt, &f, &arg))
        return(NULL);
    ctxt = (xmlParserCtxtPtr) PyparserCtxt_Get(pyobj_ctxt);
    Py_XINCREF(f);
    ((xmlParserCtxtPyCtxt *)ctxt->_private)->errorFunc = f;
    Py_XINCREF(arg);
    ((xmlParserCtxtPyCtxt *)ctxt->_private)->errorFuncArg = arg;

    ctxt->sax->error = libxml_xmlParserCtxtErrorFuncHandler;
    ctxt->vctxt.error = libxml_xmlParserCtxtErrorFuncHandler;

    py_retval = libxml_intWrap(1);
    return(py_retval);
}

It involves storing the python callback in the _private field
of xmlParserCtxt in a structure like this:

   Hum, yes that could work

typedef struct 
{
    PyObject *errorFunc;
    PyObject *errorFuncArg;
    PyObject *warningFunc;
    PyObject *warningFuncArg;
} xmlParserCtxtPyCtxt;

That _private field would be initialized in libxml_xmlParserCtxtPtrWrap
and destroyed in libxml_xmlFreeParserCtxt.

  I'm wondering if this really covers all cases. It seems okay but
a bit of checking seems necessary

xmlParserCtxtErrorFuncHandler would then simply build the message string
and call _private->errorFunc(_private->errorFuncArg,message).

My early experiments show it's doable.
Does this make any sense at all?

  Yes, I'm a bit annoyed of using the _private field, but
since that's specific to the Python wrappers, why not.

Is there a simpler approach, or something I missed,
or a different, preferred approach?
Should I go further and submit a complete patch?

  You need it, if you provide a patch which works that sounds fine :-)

Daniel

-- 
Daniel Veillard      | Red Hat Network https://rhn.redhat.com/
veillard redhat com  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]