[Lxml-checkins] r32444 - in lxml/trunk: . doc src/lxml
scoder at codespeak.net
scoder at codespeak.net
Mon Sep 18 15:54:15 CEST 2006
Author: scoder
Date: Mon Sep 18 15:54:12 2006
New Revision: 32444
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/doc/api.txt
lxml/trunk/src/lxml/xslt.pxd
lxml/trunk/src/lxml/xslt.pxi
Log:
XSLT profiling support
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Mon Sep 18 15:54:12 2006
@@ -8,6 +8,8 @@
Features added
--------------
+* XSLT profiling support (``profile_run`` keyword)
+
* countchildren() method on objectify.ObjectifiedElement
* Support custom elements for tree nodes in lxml.objectify
Modified: lxml/trunk/doc/api.txt
==============================================================================
--- lxml/trunk/doc/api.txt (original)
+++ lxml/trunk/doc/api.txt Mon Sep 18 15:54:12 2006
@@ -689,6 +689,25 @@
.. _`document loader documentation`: resolvers.html
+If you want to know how your stylesheet performed, pass the ``profile_run``
+keyword to the transform::
+
+ >>> result = transform(doc, a="/a/b/text()", profile_run=True)
+ >>> profile = result.xslt_profile
+
+The value of the ``xslt_profile`` property is an ElementTree with profiling
+data about each template, similar to the following::
+
+ <profile>
+ <template rank="1" match="/" name="" mode="" calls="1" time="1" average="1"/>
+ </profile>
+
+Note that this is a read-only document. You must not move any of its elements
+to other documents. Please deep-copy the document if you need to modify it.
+If you want to free it from memory, just do::
+
+ >>> del result.xslt_profile
+
RelaxNG
-------
Modified: lxml/trunk/src/lxml/xslt.pxd
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxd (original)
+++ lxml/trunk/src/lxml/xslt.pxd Mon Sep 18 15:54:12 2006
@@ -21,6 +21,7 @@
xsltDocument* document
void* _private
xmlDict* dict
+ int profile
cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc)
cdef void xsltFreeStylesheet(xsltStylesheet* sheet)
@@ -97,6 +98,7 @@
xsltSecurityCheck func)
cdef int xsltSetCtxtSecurityPrefs(xsltSecurityPrefs* sec,
xsltTransformContext* ctxt)
+ cdef xmlDoc* xsltGetProfileInformation(xsltTransformContext* ctxt)
cdef extern from "libxslt/extra.h":
cdef char* XSLT_LIBXSLT_NAMESPACE
Modified: lxml/trunk/src/lxml/xslt.pxi
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxi (original)
+++ lxml/trunk/src/lxml/xslt.pxi Mon Sep 18 15:54:12 2006
@@ -337,12 +337,14 @@
def __get__(self):
return self._error_log.copy()
- def __call__(self, _input, **_kw):
+ def __call__(self, _input, profile_run=False, **_kw):
cdef python.PyThreadState* state
cdef _XSLTContext context
cdef _Document input_doc
cdef _NodeBase root_node
cdef _Document result_doc
+ cdef _Document profile_doc
+ cdef xmlDoc* c_profile_doc
cdef _XSLTResolverContext resolver_context
cdef xslt.xsltTransformContext* transform_ctxt
cdef xmlDoc* c_result
@@ -375,6 +377,9 @@
if self._access_control is not None:
self._access_control._register_in_context(transform_ctxt)
+ if profile_run:
+ transform_ctxt.profile = 1
+
transform_ctxt._private = <python.PyObject*>self._xslt_resolver_context
kw_count = python.PyDict_Size(_kw)
@@ -411,6 +416,11 @@
# deallocate space for parameters
python.PyMem_Free(params)
+ if transform_ctxt.profile:
+ c_profile_doc = xslt.xsltGetProfileInformation(transform_ctxt)
+ if c_profile_doc is not NULL:
+ profile_doc = _documentFactory(c_profile_doc, input_doc._parser)
+
context.free_context()
_destroyFakeDoc(input_doc._c_doc, c_doc)
@@ -434,10 +444,10 @@
raise XSLTApplyError, message
result_doc = _documentFactory(c_result, input_doc._parser)
- return _xsltResultTreeFactory(result_doc, self)
+ return _xsltResultTreeFactory(result_doc, self, profile_doc)
- def apply(self, _input, **_kw):
- return self.__call__(_input, **_kw)
+ def apply(self, _input, profile_run=False, **_kw):
+ return self.__call__(_input, profile_run, **_kw)
def tostring(self, _ElementTree result_tree):
"""Save result doc to string based on stylesheet output method.
@@ -446,6 +456,7 @@
cdef class _XSLTResultTree(_ElementTree):
cdef XSLT _xslt
+ cdef _Document _profile
cdef _saveToStringAndSize(self, char** s, int* l):
cdef _Document doc
cdef int r
@@ -489,10 +500,26 @@
tree.xmlFree(s)
return _stripEncodingDeclaration(result)
-cdef _xsltResultTreeFactory(_Document doc, XSLT xslt):
+ property xslt_profile:
+ """Return an ElementTree with profiling data for the stylesheet run.
+ """
+ def __get__(self):
+ cdef _Element root
+ if self._profile is None:
+ return None
+ root = self._profile.getroot()
+ if root is None:
+ return None
+ return ElementTree(root)
+
+ def __del__(self):
+ self._profile = None
+
+cdef _xsltResultTreeFactory(_Document doc, XSLT xslt, _Document profile):
cdef _XSLTResultTree result
result = <_XSLTResultTree>_newElementTree(doc, None, _XSLTResultTree)
result._xslt = xslt
+ result._profile = profile
return result
# functions like "output" and "write" are a potential security risk, but we
More information about the lxml-checkins
mailing list