1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-07-29 15:41:13 +03:00

plugged the extension of the engine with python defined functions added a

* python/libxlst.c python/libxslt-python-api.xml
  python/libxsltclass.txt: plugged the extension of the engine
  with python defined functions
* python/tests/Makefile.am python/tests/extfunc.py: added a
  basic test, still a memleak, cleanup function needed.
Daniel
This commit is contained in:
Daniel Veillard
2002-02-06 18:48:48 +00:00
parent 584f279f53
commit 09af30e51e
6 changed files with 163 additions and 2 deletions

View File

@ -12,6 +12,13 @@
<arg name='doc' type='xmlDocPtr' info='a parsed XML document'/>
<arg name='params' type='pythonObject' info='the parameters dictionnary'/>
</function>
<function name='xsltRegisterExtModuleFunction' file='python'>
<info>Register a Python written function to the XSLT engine</info>
<return type='int' info="0 in case of success, -1 in case of error"/>
<arg name='name' type='xmlChar *' info='the function name'/>
<arg name='URI' type='xmlChar *' info='the namespace or NULL'/>
<arg name='f' type='pythonObject' info='the python function'/>
</function>
<!--
<function name='xsltRegisterXPathFunction' file='python'>
<info>Register a Python written function to the XPath interpreter</info>

View File

@ -141,6 +141,99 @@ libxslt_xmlDumpMemory(PyObject *self, PyObject *args) {
return(Py_None);
}
/************************************************************************
* *
* Extending the API *
* *
************************************************************************/
static xmlHashTablePtr libxslt_extModuleFunctions = NULL;
static void
libxslt_xmlXPathFuncCallback(xmlXPathParserContextPtr ctxt, int nargs) {
PyObject *list, *cur, *result;
xmlXPathObjectPtr obj;
xmlXPathContextPtr rctxt;
PyObject *current_function = NULL;
const xmlChar *name;
const xmlChar *ns_uri;
int i;
if (ctxt == NULL)
return;
rctxt = ctxt->context;
if (rctxt == NULL)
return;
name = rctxt->function;
ns_uri = rctxt->functionURI;
#ifdef DEBUG_XPATH
printf("libxslt_xmlXPathFuncCallback called name %s URI %s\n", name, ns_uri);
#endif
/*
* Find the function, it should be there it was there at lookup
*/
current_function = xmlHashLookup2(libxslt_extModuleFunctions,
name, ns_uri);
if (current_function == NULL) {
printf("libxslt_xmlXPathFuncCallback: internal error %s not found !\n",
name);
return;
}
list = PyTuple_New(nargs);
for (i = 0;i < nargs;i++) {
obj = valuePop(ctxt);
cur = libxml_xmlXPathObjectPtrWrap(obj);
PyTuple_SetItem(list, i, cur);
}
result = PyEval_CallObject(current_function, list);
Py_DECREF(list);
obj = libxml_xmlXPathObjectPtrConvert(result);
valuePush(ctxt, obj);
}
PyObject *
libxslt_xsltRegisterExtModuleFunction(PyObject *self, PyObject *args) {
PyObject *py_retval;
int ret = 0;
xmlChar *name;
xmlChar *ns_uri;
PyObject *pyobj_f;
if (!PyArg_ParseTuple(args, "szO:registerXPathFunction",
&name, &ns_uri, &pyobj_f))
return(NULL);
if ((name == NULL) || (pyobj_f == NULL)) {
py_retval = libxml_intWrap(-1);
return(py_retval);
}
#ifdef DEBUG_XPATH
printf("libxslt_xsltRegisterExtModuleFunction(%s, %s) called\n",
name, ns_uri);
#endif
if (libxslt_extModuleFunctions == NULL)
libxslt_extModuleFunctions = xmlHashCreate(10);
if (libxslt_extModuleFunctions == NULL) {
py_retval = libxml_intWrap(-1);
return(py_retval);
}
ret = xmlHashAddEntry2(libxslt_extModuleFunctions, name, ns_uri, pyobj_f);
if (ret != 0) {
py_retval = libxml_intWrap(-1);
return(py_retval);
}
ret = xsltRegisterExtModuleFunction(name, ns_uri,
libxslt_xmlXPathFuncCallback);
py_retval = libxml_intWrap((int) ret);
return(py_retval);
}
/************************************************************************
* *
* Some customized front-ends *
@ -156,7 +249,7 @@ libxslt_xsltApplyStylesheet(PyObject *self, PyObject *args) {
xmlDocPtr doc;
PyObject *pyobj_doc;
PyObject *pyobj_params;
char **params;
const char **params;
if (!PyArg_ParseTuple(args, "OOO:xsltApplyStylesheet", &pyobj_style, &pyobj_doc, &pyobj_params))
return(NULL);

View File

@ -18,6 +18,9 @@ registerAllExtras()
# functions from module functions
registerAllFunctions()
# functions from module python
registerExtModuleFunction()
# functions from module transform
setXIncludeDefault()
xincludeDefault()

View File

@ -1,7 +1,8 @@
EXAMPLE_DIR = $(prefix)/share/doc/libxslt-python-$(LIBXML_VERSION)/examples
TESTS= \
basic.py
basic.py \
extfunc.py
XMLS= \
test.xml \

49
python/tests/extfunc.py Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/python -u
import sys
import libxml2
import libxslt
# Memory debug specific
libxml2.debugMemory(1)
def f(str):
import string
return string.upper(str)
libxslt.registerExtModuleFunction("foo", "http://example.com/foo", f)
styledoc = libxml2.parseDoc("""
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:foo='http://example.com/foo'
xsl:exclude-result-prefixes='foo'>
<xsl:template match='/'>
<article><xsl:value-of select='foo:foo(\"foo\")'/></article>
</xsl:template>
</xsl:stylesheet>
""")
style = libxslt.parseStylesheetDoc(styledoc)
doc = libxml2.parseDoc("<doc/>")
result = style.applyStylesheet(doc, None)
style = None
doc.freeDoc()
root = result.children
if root.name != "article":
print "Unexpected root node name"
sys.exit(1)
if root.content != "FOO":
print "Unexpected root node content, extension function failed"
sys.exit(1)
result.freeDoc()
# Memory debug specific
libxslt.cleanupGlobals()
libxml2.cleanupParser()
if libxml2.debugMemory(1) == 0:
print "OK"
else:
print "Memory leak %d bytes" % (libxml2.debugMemory(1))
libxml2.dumpMemory()