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:
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -18,6 +18,9 @@ registerAllExtras()
|
||||
# functions from module functions
|
||||
registerAllFunctions()
|
||||
|
||||
# functions from module python
|
||||
registerExtModuleFunction()
|
||||
|
||||
# functions from module transform
|
||||
setXIncludeDefault()
|
||||
xincludeDefault()
|
||||
|
@ -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
49
python/tests/extfunc.py
Executable 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()
|
Reference in New Issue
Block a user