[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