[Lxml-checkins] r52025 - in lxml/trunk: . src/lxml src/lxml/tests
scoder at codespeak.net
scoder at codespeak.net
Sun Mar 2 09:31:22 CET 2008
Author: scoder
Date: Sun Mar 2 09:31:20 2008
New Revision: 52025
Modified:
lxml/trunk/ (props changed)
lxml/trunk/TODO.txt
lxml/trunk/src/lxml/readonlytree.pxi
lxml/trunk/src/lxml/tests/test_xslt.py
lxml/trunk/src/lxml/xslt.pxd
Log:
r3664 at delle: sbehnel | 2008-03-02 08:56:19 +0100
r3650 at delle: sbehnel | 2008-02-29 21:39:21 +0100
initial import: will use read-only elements to access the XSLT tree, the input tree and the output tree
Modified: lxml/trunk/TODO.txt
==============================================================================
--- lxml/trunk/TODO.txt (original)
+++ lxml/trunk/TODO.txt Sun Mar 2 09:31:20 2008
@@ -45,6 +45,22 @@
by libxml2 (patch exists)
+XSLT extension elements
+-----------------------
+
+* implementation: one base class that represents the result parent
+
+ - .append(), .extend() and .text will add to the result tree (no .tail)
+
+ - difference: Elements should be copied, not moved? (will break
+ later changes, but this just means that Elements in the result
+ tree are immutable, including those that were added)
+
+ - how to make input tree read-only? maybe just document?
+
+ - docs: "once in the result tree, Elements must no longer be changed"?
+
+
lxml 2.0
========
Modified: lxml/trunk/src/lxml/readonlytree.pxi
==============================================================================
--- lxml/trunk/src/lxml/readonlytree.pxi (original)
+++ lxml/trunk/src/lxml/readonlytree.pxi Sun Mar 2 09:31:20 2008
@@ -207,17 +207,21 @@
cdef _ReadOnlyElementProxy NEW_RO_PROXY "PY_NEW" (object t)
cdef _ReadOnlyElementProxy _newReadOnlyProxy(
- _ReadOnlyElementProxy sourceProxy, xmlNode* c_node):
+ _ReadOnlyElementProxy source_proxy, xmlNode* c_node):
cdef _ReadOnlyElementProxy el
el = NEW_RO_PROXY(_ReadOnlyElementProxy)
el._c_node = c_node
- if sourceProxy is None:
+ _initReadOnlyProxy(el, source_proxy)
+ return el
+
+cdef inline _initReadOnlyProxy(_ReadOnlyElementProxy el,
+ _ReadOnlyElementProxy source_proxy):
+ if source_proxy is None:
el._source_proxy = el
el._dependent_proxies = [el]
else:
- el._source_proxy = sourceProxy
- python.PyList_Append(sourceProxy._dependent_proxies, el)
- return el
+ el._source_proxy = source_proxy
+ python.PyList_Append(source_proxy._dependent_proxies, el)
cdef _freeReadOnlyProxies(_ReadOnlyElementProxy sourceProxy):
cdef _ReadOnlyElementProxy el
@@ -228,3 +232,71 @@
for el in sourceProxy._dependent_proxies:
el._c_node = NULL
del sourceProxy._dependent_proxies[:]
+
+
+cdef class _ReadOnlyRootElementProxy(_ReadOnlyElementProxy):
+ """A read-only element that frees the subtree on deallocation.
+ """
+ def __dealloc__(self):
+ if self._c_node is not NULL:
+ tree.xmlFreeNode(self._c_node)
+
+cdef class _AppendOnlyElementProxy(_ReadOnlyElementProxy):
+ """A read-only element that allows adding children and changing the
+ text content (i.e. everything that adds to the subtree).
+ """
+ cpdef append(self, other_element):
+ """Append a copy of an Element to the list of children.
+ """
+ cdef xmlNode* c_next
+ cdef xmlNode* c_node
+ self._assertNode()
+ c_node = _roNodeOf(other_element)
+ c_node = _copyNodeToDoc(c_node, self._c_node.doc)
+ c_next = c_node.next
+ tree.xmlAddChild(self._c_node, c_node)
+ _moveTail(c_next, c_node)
+
+ def extend(self, elements):
+ """Append a copy of all Elements from a sequence to the list of
+ children.
+ """
+ self._assertNode()
+ for element in elements:
+ self.append(element)
+
+ property text:
+ """Text before the first subelement. This is either a string or the
+ value None, if there was no text.
+ """
+ def __get__(self):
+ self._assertNode()
+ return _collectText(self._c_node.children)
+
+ def __set__(self, value):
+ self._assertNode()
+ if isinstance(value, QName):
+ value = python.PyUnicode_FromEncodedObject(
+ _resolveQNameText(self, value), 'UTF-8', 'strict')
+ _setNodeText(self._c_node, value)
+
+cdef _AppendOnlyElementProxy _newAppendOnlyProxy(
+ _ReadOnlyElementProxy source_proxy, xmlNode* c_node):
+ cdef _AppendOnlyElementProxy el
+ el = <_AppendOnlyElementProxy>NEW_RO_PROXY(_AppendOnlyElementProxy)
+ el._c_node = c_node
+ _initReadOnlyProxy(el, source_proxy)
+ return el
+
+cdef xmlNode* _roNodeOf(element) except NULL:
+ cdef xmlNode* c_node
+ if isinstance(element, _Element):
+ c_node = (<_Element>element)._c_node
+ elif isinstance(element, _ReadOnlyElementProxy):
+ c_node = (<_ReadOnlyElementProxy>element)._c_node
+ else:
+ raise TypeError("invalid value to append()")
+
+ if c_node is NULL:
+ raise TypeError("invalid element")
+ return c_node
Modified: lxml/trunk/src/lxml/tests/test_xslt.py
==============================================================================
--- lxml/trunk/src/lxml/tests/test_xslt.py (original)
+++ lxml/trunk/src/lxml/tests/test_xslt.py Sun Mar 2 09:31:20 2008
@@ -604,6 +604,26 @@
self.assertEquals(self._rootstring(result),
'<A>X</A>')
+ def test_extension_element(self):
+ tree = self.parse('<a><b>B</b></a>')
+ style = self.parse('''\
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:myns="testns"
+ extension-element-prefixes="myns"
+ exclude-result-prefixes="myns">
+ <xsl:template match="a">
+ <A><myns:mytext>b</myns:mytext></A>
+ </xsl:template>
+</xsl:stylesheet>''')
+
+ class mytext(etree.XSLTExtension):
+ pass
+
+ result = tree.xslt(style, extensions={})
+ self.assertEquals(self._rootstring(result),
+ '<A><b>X</b></A>')
+
def test_xslt_document_XML(self):
# make sure document('') works from parsed strings
xslt = etree.XSLT(etree.XML("""\
Modified: lxml/trunk/src/lxml/xslt.pxd
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxd (original)
+++ lxml/trunk/src/lxml/xslt.pxd Sun Mar 2 09:31:20 2008
@@ -1,4 +1,4 @@
-from tree cimport xmlDoc, xmlDict
+from tree cimport xmlDoc, xmlNode, xmlDict
from xpath cimport xmlXPathContext, xmlXPathFunction
cdef extern from "libxslt/xslt.h":
@@ -22,6 +22,11 @@
void* _private
xmlDict* dict
int profile
+ xmlNode* node
+ xmlDoc* output
+ xmlNode* insert
+
+ ctypedef struct xsltStackElem
cdef xsltStylesheet* xsltParseStylesheetDoc(xmlDoc* doc) nogil
cdef void xsltFreeStylesheet(xsltStylesheet* sheet) nogil
@@ -59,6 +64,9 @@
char** params, char* output,
void* profile,
xsltTransformContext* context) nogil
+ cdef void xsltProcessOneNode(xsltTransformContext* ctxt,
+ xmlNode* contextNode,
+ xsltStackElem* params)
cdef xsltTransformContext* xsltNewTransformContext(xsltStylesheet* style,
xmlDoc* doc) nogil
cdef void xsltFreeTransformContext(xsltTransformContext* context) nogil
More information about the lxml-checkins
mailing list