diff options
author | Daniel Veillard <veillard@src.gnome.org> | 2006-12-11 11:11:06 +0000 |
---|---|---|
committer | Daniel Veillard <veillard@src.gnome.org> | 2006-12-11 11:11:06 +0000 |
commit | 50605fed229824b4a77135fe8b0a1973ca3e1b11 (patch) | |
tree | 630af2a78c78bced42d9a809b7406e33ebafdfb5 /python | |
parent | 79068441851f5fc363d75906a722c6482be0377a (diff) | |
download | libxslt-50605fed229824b4a77135fe8b0a1973ca3e1b11.tar.gz libxslt-50605fed229824b4a77135fe8b0a1973ca3e1b11.tar.bz2 libxslt-50605fed229824b4a77135fe8b0a1973ca3e1b11.zip |
applied patch from Nic James Ferrier to make stylesheets comparable and to
* configure python/generator.py python/libxsl.py
python/libxslt-python-api.xml python/libxslt.c
python/tests/2stage.py python/tests/loader.py: applied patch from
Nic James Ferrier to make stylesheets comparable and to add
transformContext handling
Daniel
Diffstat (limited to 'python')
-rwxr-xr-x | python/generator.py | 2 | ||||
-rw-r--r-- | python/libxsl.py | 31 | ||||
-rw-r--r-- | python/libxslt-python-api.xml | 50 | ||||
-rw-r--r-- | python/libxslt.c | 301 | ||||
-rw-r--r-- | python/libxsltclass.txt | 18 |
5 files changed, 400 insertions, 2 deletions
diff --git a/python/generator.py b/python/generator.py index 7b82b048..c13d6066 100755 --- a/python/generator.py +++ b/python/generator.py @@ -564,6 +564,8 @@ primary_classes = ["xpathParserContext", "xpathContext", "transformCtxt", "style classes_ancestor = { "xpathContext" : "libxml2.xpathContext", "xpathParserContext" : "libxml2.xpathParserContext", + "transformCtxt": "transformCtxtBase", + "stylesheet": "stylesheetBase", } classes_destructors = { "xpathContext" : "pass" diff --git a/python/libxsl.py b/python/libxsl.py index 56aa8f1c..503aa4ff 100644 --- a/python/libxsl.py +++ b/python/libxsl.py @@ -56,6 +56,37 @@ else: import libxsltmod import libxml2 + +class transformCtxtBase: + def __init__(self, _obj=None): + if _obj != None: + self._o = _obj; + return + self._o = None + def __hash__(self): + v = libxsltmod.xsltGetTransformContextHashCode(self._o) + return v + def __eq__(self, other): + if 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 __hash__(self): + v = libxsltmod.xsltGetStylesheetHashCode(self._o) + return v + def __eq__(self, other): + if other == None: + return 0 + v = libxsltmod.xsltCompareStylesheetsEqual(self._o, other._o) + return v + class extensionModule: def _styleInit(self, style, URI): return self.styleInit(stylesheet(_obj=style), URI) diff --git a/python/libxslt-python-api.xml b/python/libxslt-python-api.xml index 8fbaacfe..fc35e5d1 100644 --- a/python/libxslt-python-api.xml +++ b/python/libxslt-python-api.xml @@ -11,6 +11,56 @@ <arg name='style' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/> <arg name='result' type='xmlDocPtr' info='The result document'/> </function> + <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='xsltGetTransformContextHashCode' file='python'> + <info>Get the hash code of the transformContext</info> + <return type='int' info='the hash code' /> + <arg name='transformCtxt' type='xsltTransformContextPtr' info='a parsed XSLT transformContext'/> + </function> + <function name='xsltGetStylesheetHashCode' file='python'> + <info>Get the hash code of the stylesheet</info> + <return type='int' info='the hash code' /> + <arg name='stylesheet' type='xsltStylesheetPtr' info='a parsed XSLT stylesheet'/> + </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> <function name='xsltApplyStylesheet' file='python'> <info>Apply the stylesheet to the document</info> <return type='xmlDocPtr' info="the result document or NULL in case of error"/> diff --git a/python/libxslt.c b/python/libxslt.c index 6433626e..5337b7a7 100644 --- a/python/libxslt.c +++ b/python/libxslt.c @@ -20,6 +20,8 @@ #include "libxslt_wrap.h" #include "libxslt-py.h" +#include <stdio.h> + #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(vsnprintf) #define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a) #elif defined(XSLT_NEED_TRIO) @@ -55,6 +57,7 @@ libxslt_xsltStylesheetPtrWrap(xsltStylesheetPtr style) { } ret = PyCObject_FromVoidPtrAndDesc((void *) style, (char *)"xsltStylesheetPtr", NULL); + return(ret); } @@ -90,6 +93,81 @@ libxslt_xsltElemPreCompPtrWrap(xsltElemPreCompPtr ctxt) { return(ret); } +PyObject * +libxslt_xsltGetTransformContextHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_tctxt; + PyObject *ret; + long hash_code; + xsltTransformContextPtr tctxt; + + if (!PyArg_ParseTuple(args, (char *)"O:getTransformContextHashCode", + &py_tctxt)) + return NULL; + + tctxt = (xsltTransformContextPtr) PytransformCtxt_Get(py_tctxt); + hash_code = (long) tctxt; + + ret = PyInt_FromLong(hash_code); + return ret; +} + +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_xsltGetStylesheetHashCode(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { + PyObject *py_style; + PyObject *ret; + long hash_code; + xsltStylesheetPtr style; + + if (!PyArg_ParseTuple(args, (char *)"O:getStylesheetHashCode", + &py_style)) + return NULL; + + style = (xsltStylesheetPtr) Pystylesheet_Get(py_style); + hash_code = (long) style; + + ret = PyInt_FromLong(hash_code); + return ret; +} + + +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); +} + /************************************************************************ * * * Extending the API * @@ -423,6 +501,116 @@ libxslt_xsltRegisterExtModuleFunction(PyObject *self ATTRIBUTE_UNUSED, return(py_retval); } + +/************************************************************************ + * * + * 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); +} + + /************************************************************************ * * * Some customized front-ends * @@ -430,6 +618,119 @@ libxslt_xsltRegisterExtModuleFunction(PyObject *self ATTRIBUTE_UNUSED, ************************************************************************/ PyObject * +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 * libxslt_xsltApplyStylesheet(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) { PyObject *py_retval; xmlDocPtr c_retval; diff --git a/python/libxsltclass.txt b/python/libxsltclass.txt index 555b69f8..7ed40569 100644 --- a/python/libxsltclass.txt +++ b/python/libxsltclass.txt @@ -22,6 +22,7 @@ registerErrorHandler() registerExtModuleElement() registerExtModuleFunction() registerExtensionClass() +setLoaderFunc() # functions from module xslt cleanupGlobals() @@ -74,7 +75,9 @@ Class xpathContext(libxml2.xpathContext) # functions from module functions registerAllFunctions() -Class transformCtxt() + + +Class transformCtxt(transformCtxtBase) # accessors context() current() @@ -112,6 +115,11 @@ Class transformCtxt() plainNamespace() specialNamespace() + # functions from module python + compareTransformContextsEqual() + freeTransformContext() + transformContextHashCode() + # functions from module templates attrListTemplateProcess() attrTemplateProcess() @@ -145,7 +153,9 @@ Class transformCtxt() profileInformation() saveProfiling() setCtxtParseOptions() -Class stylesheet() + + +Class stylesheet(stylesheetBase) # accessors doc() doctypePublic() @@ -195,7 +205,11 @@ Class stylesheet() # functions from module python applyStylesheet() + applyStylesheetUser() + compareStylesheetsEqual() + newTransformContext() saveResultToString() + stylesheetHashCode() # functions from module variables parseGlobalParam() |