[xml] python wrapper for the document loading API: patch
- From: Nic James Ferrier <nferrier tapsellferrier co uk>
- To: libxml <xml gnome org>
- Subject: [xml] python wrapper for the document loading API: patch
- Date: Fri, 08 Sep 2006 22:02:00 +0100
Here is my patch for the python wrapper for the document loading API.
It now works and is complete in all but one respect. I don't seem to
be able to get the xsltGetLoaderFunc function to appear in the python
API. I think this is because the return value of the function _must_
be a pythonObject and I think there might be something wrong with the
generator in that case.
Anyway... getLoaderFunc() isn't all that necessary and I can fix it
down the line so I think this patch could be considered for inclusion.
Here's a changelog for this patch:
2006-09-08 Nic James Ferrier <nferrier tapsellferrier co uk>
* python/tests/loader.py: new test of loader API wrapper
* python/tests/2stage.py: new test of stylesheet creation, then parsing
* python/libxslt.c: new functions libxslt_xsltNewTransformContext,
libxslt_xsltFreeTransformContext, libxslt_xsltApplyStylesheetUser
* python/libxslt.c: new functions pythonDocLoaderFuncWrapper,
libxslt_xsltSetLoaderFunc, libxslt_xsltGetLoaderFunc
* python/libxslt.c: new static variable pythonDocLoaderObject
* python/libxslt.c: new functions
libxslt_xsltCompareStylesheetsEqual, libxslt_xsltCompareTransformContextsEqual
* python/libxslt-python-api.xml: add declarations for
xsltSetLoaderFunc, xsltGetLoaderFunc, xsltNewTranformContext,
xsltCompareTransformContextsEqual, xsltCompareStylesheetsEqual,
xsltApplyStylesheetUser
* python/libxsl.py: new classes transformCtxtBase, stylesheetBase
* python/generator.py: add base classes for transformCtxt,
stylesheet
Daniel, would you consider including this please?
--
Nic Ferrier
http://www.tapsellferrier.co.uk for all your tapsell ferrier needs
Only in ../pristine/libxslt-1.1.17/libexslt: exsltconfig.h
Only in ../pristine/libxslt-1.1.17/libxslt: xsltconfig.h
Only in ../pristine/libxslt-1.1.17/libxslt: xsltwin32config.h
Only in ../pristine/libxslt-1.1.17: libxslt.spec
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/generator.py ./python/generator.py
566a567,568
"transformCtxt": "transformCtxtBase",
"stylesheet": "stylesheetBase",
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/libxsl.py ./python/libxsl.py
58a59,83
class transformCtxtBase:
def __init__(self, _obj=None):
if _obj != None:
self._o = _obj;
return
self._o = None
def __eq__(self, other):
if self == None or other == None:
return 0
v = libxsltmod.xsltCompareTransformContextsEqual(self._o, other._o)
return v
class stylesheetBase:
def __init__(self, _obj=None):
if _obj != None:
self._o = _obj;
return
self._o = None
def __eq__(self, other):
if self == None or other == None:
return 0
v = libxsltmod.xsltCompareStylesheetsEqual(self._o, other._o)
return v
Only in ../pristine/libxslt-1.1.17/python: libxslt-py.c
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/libxslt-python-api.xml
./python/libxslt-python-api.xml
13a14,53
<function name='xsltSetLoaderFunc' file='python'>
<info>Set the function for controlling document loading</info>
<return type='long' info='0 for failure or 1 for success'/>
<arg name='loader' type='pythonObject' info='the loader function; should take: string URI,
xsltParserContext, context, type; when type == 1 the context is a stylesheet, when type == 0 the context is
a transformCtxt'/>
</function>
<function name='xsltGetLoaderFunc' file='python'>
<info>Get the function for controlling document loading</info>
<return type='pythonObject *' info='the function'/>
</function>
<function name='xsltNewTransformContext' file='python'>
<info>Create a new XSLT TransformContext</info>
<return type='xsltTransformContextPtr' info='an xslt TransformContext'/>
<arg name='style' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/>
<arg name='doc' type='xmlDocPtr' info='the input document'/>
</function>
<function name='xsltFreeTransformContext' file='python'>
<info>Free up an existing XSLT TransformContext</info>
<return type='void' info='None'/>
<arg name='transformCtxt' type='xsltTransformContextPtr' info='an existing tranformCtxt'/>
</function>
<function name='xsltCompareTransformContextsEqual' file='python'>
<info>Compare one transformCtxt with another</info>
<return type='int' info='1 in case of success, 0 or -1 in error' />
<arg name='transformCtxt' type='xsltTransformContextPtr' info='a parsed XSLT transformContext'/>
<arg name='other' type='xsltTransformContextPtr' info='a parsed XSLT transformContext'/>
</function>
<function name='xsltCompareStylesheetsEqual' file='python'>
<info>Compare one stylesheet with another</info>
<return type='int' info='1 in case of success, 0 or -1 in error' />
<arg name='stylesheet' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/>
<arg name='other' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/>
</function>
<function name='xsltApplyStylesheetUser' file='python'>
<info>Apply the stylesheet to the document</info>
<return type='xmlDocPtr' info="the result document or NULL in case of error"/>
<arg name='style' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/>
<arg name='doc' type='xmlDocPtr' info='a parsed XML document'/>
<arg name='params' type='pythonObject' info='the parameters dictionnary'/>
<arg name='transformCtxt' type='xsltTransformContextPtr' info='transformation context'/>
</function>
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/libxslt.c ./python/libxslt.c
22a23,24
#include <stdio.h>
57a60,62
// Py_AddAttr(ret, cmp_function_impl);
92a98,135
PyObject *
libxslt_xsltCompareTransformContextsEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_tctxt1, *py_tctxt2;
xsltTransformContextPtr tctxt1, tctxt2;
if (!PyArg_ParseTuple(args, (char *)"OO:compareTransformContextsEqual",
&py_tctxt1, &py_tctxt2))
return NULL;
tctxt1 = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt1);
tctxt2 = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt2);
if ( tctxt1 == tctxt2 )
return Py_BuildValue((char *)"i", 1);
else
return Py_BuildValue((char *)"i", 0);
}
PyObject *
libxslt_xsltCompareStylesheetsEqual(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_style1, *py_style2;
xsltStylesheetPtr style1, style2;
if (!PyArg_ParseTuple(args, (char *)"OO:compareStylesheetsEqual",
&py_style1, &py_style2))
return NULL;
style1 = (xsltStylesheetPtr) Pystylesheet_Get(py_style1);
style2 = (xsltStylesheetPtr) Pystylesheet_Get(py_style2);
if ( style1 == style2 )
return Py_BuildValue((char *)"i", 1);
else
return Py_BuildValue((char *)"i", 0);
}
425a469,571
/************************************************************************
* *
* Document loading front-ends *
* *
************************************************************************/
static PyObject *pythonDocLoaderObject = NULL;
static xmlDocPtr
pythonDocLoaderFuncWrapper(const xmlChar * URI, xmlDictPtr dict, int options,
void *ctxt ATTRIBUTE_UNUSED,
xsltLoadType type ATTRIBUTE_UNUSED)
{
xmlParserCtxtPtr pctxt;
xmlDocPtr doc;
pctxt = xmlNewParserCtxt();
if (pctxt == NULL)
return(NULL);
if ((dict != NULL) && (pctxt->dict != NULL)) {
xmlDictFree(pctxt->dict);
pctxt->dict = NULL;
}
if (dict != NULL) {
pctxt->dict = dict;
xmlDictReference(pctxt->dict);
#ifdef WITH_XSLT_DEBUG
xsltGenericDebug(xsltGenericDebugContext,
"Reusing dictionary for document\n");
#endif
}
xmlCtxtUseOptions(pctxt, options);
// Now pass to python the URI, the xsltParserContext and the context
// (either a transformContext or a stylesheet) and get back an xmlDocPtr
if (pythonDocLoaderObject != NULL) {
PyObject *ctxtobj, *pctxtobj, *result;
pctxtobj = libxml_xmlParserCtxtPtrWrap(pctxt);
if (type == XSLT_LOAD_DOCUMENT) {
ctxtobj = libxslt_xsltTransformContextPtrWrap(ctxt);
result = PyObject_CallFunction(pythonDocLoaderObject,
(char *) "(sOOi)", URI, pctxtobj, ctxtobj, 0);
}
else {
ctxtobj = libxslt_xsltStylesheetPtrWrap(ctxt);
result = PyObject_CallFunction(pythonDocLoaderObject,
(char *) "(sOOi)", URI, pctxtobj, ctxtobj, 1);
}
Py_XDECREF(pctxtobj);
if (result != NULL) {
// The return value should be the document
// Should we test it somehow before getting the C object from it?
PyObject *py_doc = PyObject_GetAttrString(result, "_o");
doc = PyxmlNode_Get(py_doc);
// do we have to DECCREF the result??
}
}
if (! pctxt->wellFormed) {
if (doc != NULL) {
xmlFreeDoc(doc);
}
if (pctxt->myDoc != NULL) {
doc = NULL;
xmlFreeDoc(pctxt->myDoc);
pctxt->myDoc = NULL;
}
}
// xmlFreeParserCtxt(pctxt); // libc complains about double free-ing with this line
return(doc);
}
PyObject *
libxslt_xsltSetLoaderFunc(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
PyObject *loader;
if (!PyArg_ParseTuple(args, (char *)"O:libxslt_xsltSetLoaderFunc",
&loader))
return(NULL);
pythonDocLoaderObject = loader;
xsltSetLoaderFunc(pythonDocLoaderFuncWrapper);
py_retval = PyInt_FromLong(0);
return(py_retval);
}
PyObject *
libxslt_xsltGetLoaderFunc(void) {
PyObject *py_retval;
py_retval = pythonDocLoaderObject;
return(py_retval);
}
432a579,691
libxslt_xsltNewTransformContext(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
PyObject *pyobj_style;
PyObject *pyobj_doc;
xsltStylesheetPtr style;
xmlDocPtr doc;
xsltTransformContextPtr c_retval;
if (!PyArg_ParseTuple(args, (char *) "OO:xsltNewTransformContext",
&pyobj_style, &pyobj_doc))
return(NULL);
style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style);
doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
c_retval = xsltNewTransformContext(style, doc);
py_retval = libxslt_xsltTransformContextPtrWrap((xsltTransformContextPtr) c_retval);
return (py_retval);
}
PyObject *
libxslt_xsltFreeTransformContext(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_tctxt;
xsltTransformContextPtr tctxt;
if (!PyArg_ParseTuple(args, (char *) "O:xsltFreeTransformContext", &py_tctxt))
return(NULL);
tctxt = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt);
xsltFreeTransformContext(tctxt);
// Return None
Py_INCREF(Py_None);
return(Py_None);
}
PyObject *
libxslt_xsltApplyStylesheetUser(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
xmlDocPtr c_retval;
xsltStylesheetPtr style;
PyObject *pyobj_style;
xmlDocPtr doc;
xsltTransformContextPtr transformCtxt;
PyObject *pyobj_doc;
PyObject *pyobj_params;
PyObject *pyobj_transformCtxt;
const char **params = NULL;
int len = 0, i = 0, j;
PyObject *name;
PyObject *value;
if (!PyArg_ParseTuple(args, (char *) "OOOO:xsltApplyStylesheetUser",
&pyobj_style, &pyobj_doc, &pyobj_params, &pyobj_transformCtxt))
return(NULL);
if (pyobj_params != Py_None) {
if (PyDict_Check(pyobj_params)) {
len = PyDict_Size(pyobj_params);
if (len > 0) {
params = (const char **) xmlMalloc((len + 1) * 2 *
sizeof(char *));
if (params == NULL) {
printf("libxslt_xsltApplyStylesheet: out of memory\n");
Py_INCREF(Py_None);
return(Py_None);
}
j = 0;
while (PyDict_Next(pyobj_params, &i, &name, &value)) {
const char *tmp;
int size;
tmp = PyString_AS_STRING(name);
size = PyString_GET_SIZE(name);
params[j * 2] = (char *) xmlCharStrndup(tmp, size);
if (PyString_Check(value)) {
tmp = PyString_AS_STRING(value);
size = PyString_GET_SIZE(value);
params[(j * 2) + 1] = (char *)
xmlCharStrndup(tmp, size);
} else {
params[(j * 2) + 1] = NULL;
}
j = j + 1;
}
params[j * 2] = NULL;
params[(j * 2) + 1] = NULL;
}
} else {
printf("libxslt_xsltApplyStylesheet: parameters not a dict\n");
Py_INCREF(Py_None);
return(Py_None);
}
}
style = (xsltStylesheetPtr) Pystylesheet_Get(pyobj_style);
doc = (xmlDocPtr) PyxmlNode_Get(pyobj_doc);
transformCtxt = (xsltTransformContextPtr) PytransformCtxt_Get(pyobj_transformCtxt);
c_retval = xsltApplyStylesheetUser(style, doc, params, NULL, NULL, transformCtxt);
py_retval = libxml_xmlDocPtrWrap((xmlDocPtr) c_retval);
if (params != NULL) {
if (len > 0) {
for (i = 0;i < 2 * len;i++) {
if (params[i] != NULL)
xmlFree((char *)params[i]);
}
xmlFree(params);
}
}
return(py_retval);
}
PyObject *
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/tests/2stage.py
./python/tests/2stage.py
0a1,22
#!/usr/bin/python
import libxslt
import libxml2
import sys
styledoc = libxml2.parseDoc("""
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:template match='/'>
<x><xsl:value-of select='*'/></x>
</xsl:template>
</xsl:stylesheet>
""")
style = libxslt.newStylesheet()
style.parseStylesheetProcess(styledoc)
testdoc = libxml2.parseDoc("<a>hello!</a>")
result = style.applyStylesheet(testdoc, {})
result.dump(sys.stdout)
# End
diff -x '*~' --unidirectional-new-file -r ../pristine/libxslt-1.1.17/python/tests/loader.py
./python/tests/loader.py
0a1,94
import libxslt
import libxml2
import sys
import pdb
savedTC1 = None
savedTC2 = None
savedStyle1 = None
savedStyle2 = None
def fn(url, pctx, ctx, type):
global savedTC1
global savedTC2
global savedStyle1
global savedStyle2
try:
if type == 0:
tc = libxslt.transformCtxt(_obj=ctx)
if savedTC1 == tc:
print "matched TC1!"
if savedTC2 == tc:
print "matched TC2!"
pctxt = libxml2.parserCtxt(_obj=pctx)
doc = pctxt.ctxtReadDoc("""<?xml version='1.0'?><b>Goodbye</b>""", url, "UTF-8", 2)
return doc
else:
style = libxslt.stylesheet(_obj=ctx)
if savedStyle1 == style:
print "matched savedStyle1!"
if savedStyle2 == style:
print "matched savedStyle2!"
pctxt = libxml2.parserCtxt(_obj=pctx)
doc = pctxt.ctxtReadDoc("""
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
</xsl:stylesheet>""", url, "UTF-8", 2)
return doc
except Exception, e:
print >>sys.stderr, "something went wrong: ", e
return None
def run():
libxslt.setLoaderFunc(fn)
styledoc = libxml2.parseDoc("""
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:import href='import1.xslt'/>
<xsl:template match='/'>
<x><xsl:value-of select='document("b.xml")'/></x>
</xsl:template>
</xsl:stylesheet>
""")
style = libxslt.newStylesheet()
if style:
global savedStyle1
global savedTC1
global savedTC2
savedStyle1 = style
style.parseStylesheetProcess(styledoc)
src_doc1 = libxml2.parseDoc("<a/>")
transform_ctxt1 = style.newTransformContext(src_doc1)
savedTC1 = transform_ctxt1
src_doc2 = libxml2.parseDoc("<c/>")
transform_ctxt2 = style.newTransformContext(src_doc2)
savedTC2 = transform_ctxt2
result = style.applyStylesheetUser(src_doc1, {}, transform_ctxt1)
result.dump(sys.stdout)
style.freeStylesheet()
src_doc1.freeDoc()
src_doc2.freeDoc()
transform_ctxt1.freeTransformContext()
transform_ctxt2.freeTransformContext()
#print libxslt.getLoaderFunc()
run()
# End
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]