summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--configure.in1
-rwxr-xr-xpython/generator.py2
-rw-r--r--python/libxsl.py31
-rw-r--r--python/libxslt-python-api.xml50
-rw-r--r--python/libxslt.c301
-rw-r--r--python/libxsltclass.txt18
7 files changed, 409 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index a9b2f80f..65c71bd9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Dec 11 12:13:14 CET 2006 Daniel Veillard <daniel@veillard.com>
+
+ * 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
+
Sat Dec 9 15:22:34 PST 2006 William Brack <wbrack@mmm.com.hk>
* libexslt/functions.c: changed handling of function params
diff --git a/configure.in b/configure.in
index 73e1b789..bf93c3a3 100644
--- a/configure.in
+++ b/configure.in
@@ -183,6 +183,7 @@ if test "$with_python" != "no" ; then
fi
if test "$PYTHON" != ""
then
+ echo "PYTHON is pointing at $PYTHON"
PYTHON_VERSION=`$PYTHON -c "import sys; print sys.version[[0:3]]"`
echo Found Python version $PYTHON_VERSION
LIBXML2_PYTHON=`$PYTHON -c "try : import libxml2 ; print 1
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()