[Lxml-checkins] r50464 - in lxml/trunk: . src/lxml
scoder at codespeak.net
scoder at codespeak.net
Wed Jan 9 19:31:38 CET 2008
Author: scoder
Date: Wed Jan 9 19:31:38 2008
New Revision: 50464
Modified:
lxml/trunk/ (props changed)
lxml/trunk/src/lxml/extensions.pxi
lxml/trunk/src/lxml/python.pxd
Log:
r3211 at delle: sbehnel | 2008-01-08 21:02:16 +0100
return a string subclass for XPath string results that points to the source Element
Modified: lxml/trunk/src/lxml/extensions.pxi
==============================================================================
--- lxml/trunk/src/lxml/extensions.pxi (original)
+++ lxml/trunk/src/lxml/extensions.pxi Wed Jan 9 19:31:38 2008
@@ -522,12 +522,9 @@
# XSLT: can it leak when merging trees from multiple sources?
c_node = tree.xmlDocCopyNode(c_node, doc._c_doc, 1)
value = _elementFactory(doc, c_node)
- elif c_node.type == tree.XML_TEXT_NODE:
- value = funicode(c_node.content)
- elif c_node.type == tree.XML_ATTRIBUTE_NODE:
- s = tree.xmlNodeGetContent(c_node)
- value = funicode(s)
- tree.xmlFree(s)
+ elif c_node.type == tree.XML_TEXT_NODE or \
+ c_node.type == tree.XML_ATTRIBUTE_NODE:
+ value = _newElementStringResult(c_node, doc)
elif c_node.type == tree.XML_NAMESPACE_DECL:
s = (<xmlNs*>c_node).href
if s is NULL:
@@ -561,6 +558,56 @@
xpath.xmlXPathFreeObject(xpathObj)
################################################################################
+# special str/unicode subclasses
+
+cdef class _ElementStringResult(python.unicode):
+ cdef _Element parent
+ cdef readonly object is_tail
+ cdef readonly object is_text
+ cdef readonly object is_attribute
+
+ def getparent(self):
+ return self.parent
+
+cdef object _newElementStringResult(xmlNode* c_node, _Document doc):
+ cdef _ElementStringResult element_string
+ cdef xmlNode* c_element
+ cdef char* s
+ cdef bint is_attribute, is_tail
+
+ if c_node.type == tree.XML_ATTRIBUTE_NODE:
+ is_attribute = 1
+ is_tail = 0
+ s = tree.xmlNodeGetContent(c_node)
+ value = python.PyUnicode_DecodeUTF8(s, cstd.strlen(s), NULL)
+ tree.xmlFree(s)
+ c_element = NULL
+ else:
+ #assert c_node.type == tree.XML_TEXT_NODE, "invalid node type"
+ is_attribute = 0
+ # tail text?
+ value = python.PyUnicode_DecodeUTF8(
+ c_node.content, cstd.strlen(c_node.content), NULL)
+ c_element = _previousElement(c_node)
+ is_tail = c_element is not NULL
+
+ if c_element is NULL:
+ # non-tail text or attribute text
+ c_element = c_node.parent
+ while c_element is not NULL and not _isElement(c_element):
+ c_element = c_element.parent
+
+ if c_element is NULL:
+ return value
+
+ element_string = _ElementStringResult(value)
+ element_string.parent = _elementFactory(doc, c_element)
+ element_string.is_attribute = is_attribute
+ element_string.is_tail = is_tail
+ element_string.is_text = not (is_tail or is_attribute)
+ return element_string
+
+################################################################################
# callbacks for XPath/XSLT extension functions
cdef void _extension_function_call(_BaseContext context, function,
Modified: lxml/trunk/src/lxml/python.pxd
==============================================================================
--- lxml/trunk/src/lxml/python.pxd (original)
+++ lxml/trunk/src/lxml/python.pxd Wed Jan 9 19:31:38 2008
@@ -16,6 +16,9 @@
cdef object stop
cdef object step
+ ctypedef class __builtin__.unicode [object PyUnicodeObject]:
+ pass
+
cdef FILE* PyFile_AsFile(object p)
cdef int PyFile_Check(object p)
cdef object PyFile_Name(object p)
More information about the lxml-checkins
mailing list