|
List Info
Thread: adding transformContexts to Python
|
|
| adding transformContexts to Python |

|
2006-08-31 14:50:10 |
Right now there are some things that you can't do in the
Python layer
because it's not possible to pre-create a TransformContext
and apply a
transformation with one.
So I thought I'd do this and I just want some sanity
checking on the
plan:
- add a function:
libxslt.newTransformContext(doc, stylesheet)
- add a method to the stylesheet class:
applyStylesheetUser(self, doc, params, transformContext)
So the method of doing this sort of thing will be:
stylesheet =
libxslt.parseStylesheetFile("somefilename.xslt")
src_doc =
libxml2.parseFile("someotherfilename.xml")
tc = libxslt.newTransformContext(src_doc, stylesheet)
result = stylesheet.applyStylesheetUser(src_doc, {}, tc)
During the transformation the transform context will be
available to
extension functions and the resolver and so on.
Out of interest, I have 2 reasons for doing this:
1. doing memory recovery of resources created by extension
functions
Extension functions could register resources to be
collected in a
map, keyed by the transform context. When the application
is
finished a clean up routine can be run, collecting
everything in
the map for the transformContext just finished.
2. doing per-transfrom entity resolution
When the resolver is called it can get the xpathContext
of the
call. Which means that it could make a decision on where
to look
for entitys based on something in the xpathContext.
This facilitates things like multiple heirarchies of
resolution
sources.
--
Nic Ferrier
http://www.tapsellfer
rier.co.uk for all your tapsell ferrier needs
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| adding transformContexts to Python |

|
2006-08-31 15:46:42 |
On Thu, Aug 31, 2006 at 03:50:10PM +0100, Nic James Ferrier
wrote:
> Right now there are some things that you can't do in
the Python layer
> because it's not possible to pre-create a
TransformContext and apply a
> transformation with one.
>
> So I thought I'd do this and I just want some sanity
checking on the
> plan:
>
> - add a function:
>
> libxslt.newTransformContext(doc, stylesheet)
>
> - add a method to the stylesheet class:
>
> applyStylesheetUser(self, doc, params,
transformContext)
>
>
> So the method of doing this sort of thing will be:
>
> stylesheet =
libxslt.parseStylesheetFile("somefilename.xslt")
> src_doc =
libxml2.parseFile("someotherfilename.xml")
> tc = libxslt.newTransformContext(src_doc, stylesheet)
> result = stylesheet.applyStylesheetUser(src_doc, {},
tc)
>
> During the transformation the transform context will be
available to
> extension functions and the resolver and so on.
Okay,
>
> Out of interest, I have 2 reasons for doing this:
>
> 1. doing memory recovery of resources created by
extension functions
>
> Extension functions could register resources to be
collected in a
> map, keyed by the transform context. When the
application is
> finished a clean up routine can be run, collecting
everything in
> the map for the transformContext just finished.
>
>
> 2. doing per-transfrom entity resolution
>
> When the resolver is called it can get the
xpathContext of the
> call. Which means that it could make a decision on
where to look
> for entitys based on something in the xpathContext.
>
> This facilitates things like multiple heirarchies of
resolution
> sources.
I agree not everything is available at the python level,
usually what
got in was driven by user interest, first myself and then
other people.
Patches to fill the gap gratefully accepted (but will be
reviewed of
course
thanks !
Daniel
--
Red Hat Virtualization group http://redhat.com/v
irtualization/
Daniel Veillard | virtualization library http://libvirt.org/
veillard redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ |
Rpmfind RPM search engine http://rpmfind.net/
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| adding transformContexts to Python |

|
2006-09-01 02:23:54 |
Daniel Veillard <veillard redhat.com> writes:
> I agree not everything is available at the python
level, usually what
> got in was driven by user interest, first myself and
then other people.
> Patches to fill the gap gratefully accepted (but will
be reviewed of
> course
I've attached a simple diff of the changed bits to
facilitate
transform content accessing.
This works for me... though I've yet to write a
comprehensive test.
Can someone shout if they think I'm on the wrong track
here.
--
Nic Ferrier
http://www.tapsellfer
rier.co.uk for all your tapsell ferrier needs
diff -u libxslt-1.1.17/python/libxslt-python-api.xml
../libxslt-1.1.16/python/libxslt-python-api.xml
--- libxslt-1.1.17/python/libxslt-python-api.xml 2006-09-01
03:14:20.000000000 +0100
+++
../libxslt-1.1.16/python/libxslt-python-api.xml 2006-09-01
02:25:49.000000000 +0100
 -11,6
+11,12 
<arg name='style' type='xsltStylesheetPtr'
info='a parsed XSLT stylesheet'/>
<arg name='result' type='xmlDocPtr' info='The
result document'/>
</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='xsltApplyStylesheet'
file='python'>
<info>Apply the stylesheet to the
document</info>
<return type='xmlDocPtr' info="the result
document or NULL in case of error"/>
 -18,6
+24,14 
<arg name='doc' type='xmlDocPtr' info='a
parsed XML document'/>
<arg name='params' type='pythonObject'
info='the parameters dictionnary'/>
</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='xsltRegisterErrorHandler'
file='python'>
<info>Register a Python written function to for
error reporting. The function is called back as f(ctx,
error).</info>
<return type='int' info="1 in case of
success, 0 or -1 in case of error"/>
diff -u libxslt-1.1.17/python/libxslt.c
../libxslt-1.1.16/python/libxslt.c
--- libxslt-1.1.17/python/libxslt.c 2004-07-02
14:49:07.000000000 +0100
+++ ../libxslt-1.1.16/python/libxslt.c 2006-09-01
03:09:16.000000000 +0100
 -502,6
+502,106 
return(py_retval);
}
+
+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 sltNe
wTransformContext",
+ &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_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 sltAp
plyStylesheetUser",
+ &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_xsltSaveResultToString(PyObject *self
ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval; /* our final return value,
a python string */
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| adding transformContexts to Python |

|
2006-09-01 10:01:10 |
On Fri, Sep 01, 2006 at 03:23:54AM +0100, Nic James Ferrier
wrote:
> Daniel Veillard <veillard redhat.com> writes:
>
> > I agree not everything is available at the
python level, usually what
> > got in was driven by user interest, first myself
and then other people.
> > Patches to fill the gap gratefully accepted (but
will be reviewed of
> > course
>
> I've attached a simple diff of the changed bits to
facilitate
> transform content accessing.
>
> This works for me... though I've yet to write a
comprehensive test.
>
>
> Can someone shout if they think I'm on the wrong track
here.
Doesn't look crazy to me Tell me if
you want this to be applied
as is or if you prefer doing a bit more testing,
Daniel
--
Red Hat Virtualization group http://redhat.com/v
irtualization/
Daniel Veillard | virtualization library http://libvirt.org/
veillard redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ |
Rpmfind RPM search engine http://rpmfind.net/
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| adding transformContexts to Python |

|
2006-09-01 10:34:06 |
Daniel Veillard <veillard redhat.com> writes:
> Doesn't look crazy to me Tell me if
you want this to be applied
> as is or if you prefer doing a bit more testing,
I wrote a test for the resolver access:
import libxslt
import libxml2
import sys
import StringIO
import pdb
def xslt_resolver(url, id, ctxt):
pctxt = libxslt.xpathParserContext(_obj=ctxt)
xpc = pctxt.context()
doc = xpc.contextDoc()
if url == "someimport.xslt":
f =
StringIO.StringIO("""<?xml
version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns sl=&
quot;http://www.w3.or
g/1999/XSL/Transform">
<xsl:template match="/xxx">
<sexy/>
</xsl:template>
</xsl:stylesheet>
""")
return f
return None
def test():
libxml2.setEntityLoader(xslt_resolver)
src_doc = libxml2.parseDoc("<a/>")
style_doc =
libxml2.parseDoc("""<?xml
version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns sl=&
quot;http://www.w3.or
g/1999/XSL/Transform">
<xsl:import
href="someimport.xslt"/>
<xsl:template match="/">
<goodbye/>
</xsl:template>
</xsl:stylesheet>
""")
style = libxslt.parseStylesheetDoc(style_doc)
if style:
transform_ctxt =
style.newTransformContext(src_doc)
result = style.applyStylesheetUser(src_doc, {},
transform_ctxt)
result.dump(sys.stdout)
pdb.runcall(test)
When I run this on UNPATCHED libxslt (deb 1.1.17-2) it
segfaults at
line 9.
It appears that this function:
libxsltmod.xsltXPathGetContextDoc
is the immediate cause of the fault... but I'm guessing the
problem is
with the python code putting the values into the C.
I get the same problem with my patched code... can you shed
any light
on this?
--
Nic Ferrier
http://www.tapsellfer
rier.co.uk for all your tapsell ferrier needs
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| varying entity resolution (was Re:
adding transformContexts to Python) |

|
2006-09-01 14:58:18 |
Replying to myself:
> I wrote a test for the resolver access:
<snip/>
> def xslt_resolver(url, id, ctxt):
> pctxt = libxslt.xpathParserContext(_obj=ctxt)
> xpc = pctxt.context()
>
> if url == "someimport.xslt":
> f =
StringIO.StringIO("""<?xml
version="1.0" encoding="utf-8"?>
> <xsl:stylesheet version="1.0"
> xmlns sl=&
quot;http://www.w3.or
g/1999/XSL/Transform">
> <xsl:template match="/xxx">
> <sexy/>
> </xsl:template>
> </xsl:stylesheet>
> """)
> return f
> return None
This breaks.
I really wanted to be able to access the
xsltTransformContext from
here.
But it appears that I've been wrong about this... the ctxt
delivered
to the resolver is an xmlParserCtxt, not an
xpathParserContext. Moreover the xmlParserCtxt doesn't seem
to have
anyway of getting to an xpathParserContext or an
xsltTransformContext.
The reason I wanted to be able to reach the tranform context
was so
that I could uniquely identify a transformation.
I've got a webapp where users can have personalized copies
of common
xslts. In the resolver I want to be able to say:
- what request is this resolution associated with?
- what is the user's id (from the http request)
- what is the correct directory to search for xslt imports
and other
entities?
If I can't do this by getting the transformContext can
anyone suggest
how I might do it?
--
Nic Ferrier
http://www.tapsellfer
rier.co.uk for all your tapsell ferrier needs
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
| adding transformContexts to Python |

|
2006-09-04 19:29:02 |
Daniel Veillard <veillard redhat.com> writes:
> Doesn't look crazy to me Tell me if
you want this to be applied
> as is or if you prefer doing a bit more testing,
Don't add it - it doesn't work.
I did some test code and it seems that, even though the
patch
correctly calls xsltApplyStylesheetUser with the correct
transformContext, an extension function examining the
transformContext
via it's xpathContext actually sees a different object.
Not sure why that is yet - clearly something is fubar.
I'm stuck doing the other patch (the one for document
handling) which
is really important to me but once I've done it I'll come
back to this
one which is somewhat important to me.
Harrumph.
--
Nic Ferrier
http://www.tapsellfer
rier.co.uk for all your tapsell ferrier needs
_______________________________________________
xml mailing list, project page http://xmlsoft.org/
xml gnome.org
http://mai
l.gnome.org/mailman/listinfo/xml
|
|
[1-7]
|
|