[Lxml-checkins] r38836 - in lxml/trunk: . src/lxml

scoder at codespeak.net scoder at codespeak.net
Wed Feb 14 15:19:04 CET 2007


Author: scoder
Date: Wed Feb 14 15:19:02 2007
New Revision: 38836

Modified:
   lxml/trunk/CHANGES.txt
   lxml/trunk/src/lxml/apihelpers.pxi
   lxml/trunk/src/lxml/etree.pyx
   lxml/trunk/src/lxml/etreepublic.pxd
   lxml/trunk/src/lxml/extensions.pxi
   lxml/trunk/src/lxml/iterparse.pxi
   lxml/trunk/src/lxml/proxy.pxi
   lxml/trunk/src/lxml/public-api.pxi
   lxml/trunk/src/lxml/relaxng.pxi
   lxml/trunk/src/lxml/serializer.pxi
   lxml/trunk/src/lxml/xmlid.pxi
   lxml/trunk/src/lxml/xmlschema.pxi
   lxml/trunk/src/lxml/xpath.pxi
   lxml/trunk/src/lxml/xslt.pxi
Log:
removed now unneeded _NodeBase class, merged into _Element

Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt	(original)
+++ lxml/trunk/CHANGES.txt	Wed Feb 14 15:19:02 2007
@@ -2,8 +2,8 @@
 lxml changelog
 ==============
 
-under development
-=================
+1.2 (2007-02-14)
+================
 
 Features added
 --------------
@@ -34,6 +34,13 @@
 
 * Element.find*() did not accept QName objects as path
 
+Other changes
+-------------
+
+* code cleanup: redundant _NodeBase super class merged into _Element class
+  Note: although the impact should be zero in most cases, this change breaks
+  the compatibiliy of the public C-API
+
 
 1.1.2 (2006-10-30)
 ==================

Modified: lxml/trunk/src/lxml/apihelpers.pxi
==============================================================================
--- lxml/trunk/src/lxml/apihelpers.pxi	(original)
+++ lxml/trunk/src/lxml/apihelpers.pxi	Wed Feb 14 15:19:02 2007
@@ -10,19 +10,19 @@
         c_child = c_child.next
 
 cdef _Document _documentOrRaise(object input):
-    """Call this to get the document of a _Document, _ElementTree or _NodeBase
+    """Call this to get the document of a _Document, _ElementTree or _Element
     object, or to raise an exception if it can't be determined.
 
     Should be used in all API functions for consistency.
     """
     cdef _Document doc
-    cdef _NodeBase element
+    cdef _Element element
     if isinstance(input, _ElementTree):
         element = (<_ElementTree>input)._context_node
         if element is not None:
             doc = element._doc
-    elif isinstance(input, _NodeBase):
-        doc = (<_NodeBase>input)._doc
+    elif isinstance(input, _Element):
+        doc = (<_Element>input)._doc
     elif isinstance(input, _Document):
         doc = <_Document>input
     else:
@@ -32,17 +32,17 @@
     else:
         return doc
 
-cdef _NodeBase _rootNodeOrRaise(object input):
+cdef _Element _rootNodeOrRaise(object input):
     """Call this to get the root node of a _Document, _ElementTree or
-     _NodeBase object, or to raise an exception if it can't be determined.
+     _Element object, or to raise an exception if it can't be determined.
 
     Should be used in all API functions for consistency.
      """
-    cdef _NodeBase node
+    cdef _Element node
     if isinstance(input, _ElementTree):
         node = (<_ElementTree>input)._context_node
-    elif isinstance(input, _NodeBase):
-        node = <_NodeBase>input
+    elif isinstance(input, _Element):
+        node = <_Element>input
     elif isinstance(input, _Document):
         node = (<_Document>input).getroot()
     else:
@@ -54,27 +54,27 @@
 
 cdef _Document _documentOf(object input):
     # call this to get the document of a
-    # _Document, _ElementTree or _NodeBase object
+    # _Document, _ElementTree or _Element object
     # may return None!
-    cdef _NodeBase element
+    cdef _Element element
     if isinstance(input, _ElementTree):
         element = (<_ElementTree>input)._context_node
         if element is not None:
             return element._doc
-    elif isinstance(input, _NodeBase):
-        return (<_NodeBase>input)._doc
+    elif isinstance(input, _Element):
+        return (<_Element>input)._doc
     elif isinstance(input, _Document):
         return <_Document>input
     return None
 
-cdef _NodeBase _rootNodeOf(object input):
+cdef _Element _rootNodeOf(object input):
     # call this to get the root node of a
-    # _Document, _ElementTree or _NodeBase object
+    # _Document, _ElementTree or _Element object
     # may return None!
     if isinstance(input, _ElementTree):
         return (<_ElementTree>input)._context_node
-    elif isinstance(input, _NodeBase):
-        return <_NodeBase>input
+    elif isinstance(input, _Element):
+        return <_Element>input
     elif isinstance(input, _Document):
         return (<_Document>input).getroot()
     else:
@@ -176,7 +176,7 @@
     tree.xmlFree(c_result)
     return result
 
-cdef object _getAttributeValue(_NodeBase element, key, default):
+cdef object _getAttributeValue(_Element element, key, default):
     cdef char* c_result
     cdef char* c_tag
     ns, tag = _getNsTag(key)
@@ -192,7 +192,7 @@
     tree.xmlFree(c_result)
     return result
 
-cdef int _setAttributeValue(_NodeBase element, key, value) except -1:
+cdef int _setAttributeValue(_Element element, key, value) except -1:
     cdef xmlNs* c_ns
     cdef char* c_value
     cdef char* c_tag
@@ -207,7 +207,7 @@
         tree.xmlSetNsProp(element._c_node, c_ns, c_tag, c_value)
     return 0
 
-cdef int _delAttribute(_NodeBase element, key) except -1:
+cdef int _delAttribute(_Element element, key) except -1:
     cdef xmlAttr* c_attr
     cdef char* c_href
     ns, tag = _getNsTag(key)

Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx	(original)
+++ lxml/trunk/src/lxml/etree.pyx	Wed Feb 14 15:19:02 2007
@@ -358,6 +358,7 @@
     result._parser = parser
     return result
 
+
 cdef class DocInfo:
     "Document information provided by parser and DTD."
     cdef readonly object root_name
@@ -391,287 +392,33 @@
             else:
                 return ""
 
-cdef public class _NodeBase [ type LxmlNodeBaseType,
-                              object LxmlNodeBase ]:
-    """Base class to reference a document object and a libxml node.
+
+cdef public class _Element [ type LxmlElementType, object LxmlElement ]:
+    """Element class.  References a document object and a libxml node.
 
     By pointing to a Document instance, a reference is kept to
     _Document as long as there is some pointer to a node in it.
     """
     cdef _Document _doc
     cdef xmlNode* _c_node
-    
-    def __dealloc__(self):
-        #print "trying to free node:", <int>self._c_node
-        #displayNode(self._c_node, 0)
-        if self._c_node is not NULL:
-            unregisterProxy(self)
-            attemptDeallocation(self._c_node)
-
-cdef public class _ElementTree [ type LxmlElementTreeType,
-                                 object LxmlElementTree ]:
-    cdef _Document _doc
-    cdef _NodeBase _context_node
-
-    # Note that _doc is only used to store the original document if we do not
-    # have a _context_node.  All methods should prefer self._context_node._doc
-    # to honour tree restructuring.  _doc can happily be None!
-
-    cdef _assertHasRoot(self):
-        """We have to take care here: the document may not have a root node!
-        This can happen if ElementTree() is called without any argument and
-        the caller 'forgets' to call parse() afterwards, so this is a bug in
-        the caller program.
-        """
-        assert self._context_node is not None, \
-               "ElementTree not initialized, missing root"
-
-    def parse(self, source, _BaseParser parser=None):
-        """Updates self with the content of source and returns its root
-        """
-        cdef _Document doc
-        doc = _parseDocument(source, parser)
-        self._context_node = doc.getroot()
-        if self._context_node is None:
-            self._doc = doc
-        else:
-            self._doc = None
-        return self._context_node
-
-    def getroot(self):
-        """Gets the root element for this tree.
-        """
-        return self._context_node
-
-    def __copy__(self):
-        return ElementTree(self._context_node)
-
-    def __deepcopy__(self, memo):
-        if self._context_node is None:
-            return ElementTree()
-        else:
-            return ElementTree( self._context_node.__copy__() )
-
-    property docinfo:
-        """Information about the document provided by parser and DTD.  This
-        value is only defined for ElementTree objects based on the root node
-        of a parsed document (e.g.  those returned by the parse functions).
-        """
-        def __get__(self):
-            self._assertHasRoot()
-            return DocInfo(self._context_node._doc)
-
-    property parser:
-        """The parser that was used to parse the document in this ElementTree.
-        """
-        def __get__(self):
-            if self._context_node is not None and \
-                   self._context_node._doc is not None:
-                return self._context_node._doc._parser
-            return None
-
-    def write(self, file, encoding=None,
-              pretty_print=False, xml_declaration=None):
-        """Write the tree to a file or file-like object.
-        
-        Defaults to ASCII encoding and writing a declaration as needed.
-        """
-        cdef int c_write_declaration
-        self._assertHasRoot()
-        # suppress decl. in default case (purely for ElementTree compatibility)
-        if xml_declaration is not None:
-            c_write_declaration = bool(xml_declaration)
-            if encoding is None:
-                encoding = 'ASCII'
-        elif encoding is None:
-            encoding = 'ASCII'
-            c_write_declaration = 0
-        else:
-            encoding = encoding.upper()
-            c_write_declaration = encoding not in \
-                                  ('US-ASCII', 'ASCII', 'UTF8', 'UTF-8')
-        _tofilelike(file, self._context_node, encoding,
-                    c_write_declaration, bool(pretty_print))
-
-    def getpath(self, _NodeBase element not None):
-        """Returns a structural, absolute XPath expression to find that element.
-        """
-        cdef _Document doc
-        cdef xmlDoc* c_doc
-        cdef char* c_path
-        doc = self._context_node._doc
-        if element._doc is not doc:
-            raise ValueError, "Element is not in this tree."
-        c_doc = _fakeRootDoc(doc._c_doc, self._context_node._c_node)
-        c_path = tree.xmlGetNodePath(element._c_node)
-        _destroyFakeDoc(doc._c_doc, c_doc)
-        if c_path is NULL:
-            raise LxmlError, "Error creating node path."
-        path = c_path
-        tree.xmlFree(c_path)
-        return path
-
-    def getiterator(self, tag=None):
-        """Creates an iterator for the root element. The iterator loops over all elements
-        in this tree, in document order.
-        """
-        root = self.getroot()
-        if root is None:
-            return ()
-        return root.getiterator(tag)
-
-    def find(self, path):
-        """Finds the first toplevel element with given tag. Same as getroot().find(path).
-        """
-        self._assertHasRoot()
-        root = self.getroot()
-        if path[:1] == "/":
-            path = "." + path
-        return root.find(path)
-
-    def findtext(self, path, default=None):
-        """Finds the element text for the first toplevel element with given tag. Same as getroot().findtext(path)
-        """
-        self._assertHasRoot()
-        root = self.getroot()
-        if path[:1] == "/":
-            path = "." + path
-        return root.findtext(path, default)
-
-    def findall(self, path):
-        """Finds all toplevel elements with the given tag. Same as getroot().findall(path).
-        """
-        self._assertHasRoot()
-        root = self.getroot()
-        if path[:1] == "/":
-            path = "." + path
-        return root.findall(path)
-    
-    # extensions to ElementTree API
-    def xpath(self, _path, namespaces=None, extensions=None, **_variables):
-        """XPath evaluate in context of document.
-
-        ``namespaces`` is an optional dictionary with prefix to namespace URI
-        mappings, used by XPath.  ``extensions`` defines additional extension
-        functions.
-        
-        Returns a list (nodeset), or bool, float or string.
-
-        In case of a list result, return Element for element nodes,
-        string for text and attribute values.
-
-        Note: if you are going to apply multiple XPath expressions
-        against the same document, it is more efficient to use
-        XPathEvaluator directly.
-        """
-        self._assertHasRoot()
-        evaluator = XPathDocumentEvaluator(self, namespaces, extensions)
-        return evaluator.evaluate(_path, **_variables)
-
-    def xslt(self, _xslt, extensions=None, access_control=None, **_kw):
-        """Transform this document using other document.
-
-        xslt is a tree that should be XSLT
-        keyword parameters are XSLT transformation parameters.
-
-        Returns the transformed tree.
-
-        Note: if you are going to apply the same XSLT stylesheet against
-        multiple documents, it is more efficient to use the XSLT
-        class directly.
-        """
-        self._assertHasRoot()
-        style = XSLT(_xslt, extensions=extensions,
-                     access_control=access_control)
-        return style(self, **_kw)
-
-    def relaxng(self, relaxng):
-        """Validate this document using other document.
-
-        relaxng is a tree that should contain Relax NG XML
-
-        Returns True or False, depending on whether validation
-        succeeded.
-
-        Note: if you are going to apply the same Relax NG schema against
-        multiple documents, it is more efficient to use the RelaxNG
-        class directly.
-        """
-        self._assertHasRoot()
-        schema = RelaxNG(relaxng)
-        return schema.validate(self)
-
-    def xmlschema(self, xmlschema):
-        """Validate this document using other document.
-
-        xmlschema is a tree that should contain XML Schema XML.
-
-        Returns True or False, depending on whether validation
-        succeeded.
-
-        Note: If you are going to apply the same XML Schema against
-        multiple documents, it is more efficient to use the XMLSchema
-        class directly.
-        """
-        self._assertHasRoot()
-        schema = XMLSchema(xmlschema)
-        return schema.validate(self)
-
-    def xinclude(self):
-        """Process the XInclude nodes in this document and include the
-        referenced XML fragments.
-        """
-        cdef int result
-        # We cannot pass the XML_PARSE_NOXINCNODE option as this would free
-        # the XInclude nodes - there may still be Python references to them!
-        # Therefore, we allow XInclude nodes to be converted to
-        # XML_XINCLUDE_START nodes.  XML_XINCLUDE_END nodes are added as
-        # siblings.  Tree traversal will simply ignore them as they are not
-        # typed as elements.  The included fragment is added between the two,
-        # i.e. as a sibling, which does not conflict with traversal.
-        self._assertHasRoot()
-        if self._context_node._doc._parser != None:
-            result = xinclude.xmlXIncludeProcessTreeFlags(
-                self._context_node._c_node,
-                self._context_node._doc._parser._parse_options)
-        else:
-            result = xinclude.xmlXIncludeProcessTree(
-                self._context_node._c_node)
-        if result == -1:
-            raise XIncludeError, "XInclude processing failed"
-
-    def write_c14n(self, file):
-        """C14N write of document. Always writes UTF-8.
-        """
-        self._assertHasRoot()
-        _tofilelikeC14N(file, self._context_node)
-
-cdef _ElementTree _elementTreeFactory(_Document doc, _NodeBase context_node):
-    return _newElementTree(doc, context_node, _ElementTree)
-
-cdef _ElementTree _newElementTree(_Document doc, _NodeBase context_node,
-                                  object baseclass):
-    cdef _ElementTree result
-    result = baseclass()
-    if context_node is None and doc is not None:
-            context_node = doc.getroot()
-    if context_node is None:
-        result._doc = doc
-    result._context_node = context_node
-    return result
-
-cdef public class _Element(_NodeBase) [ type LxmlElementType,
-                                        object LxmlElement ]:
     cdef object _tag
     cdef object _attrib
+
     def _init(self):
         """Called after object initialisation.  Custom subclasses may override
         this if they recursively call _init() in the superclasses.
         """
 
+    def __dealloc__(self):
+        #print "trying to free node:", <int>self._c_node
+        #displayNode(self._c_node, 0)
+        if self._c_node is not NULL:
+            unregisterProxy(self)
+            attemptDeallocation(self._c_node)
+
     # MANIPULATORS
 
-    def __setitem__(self, Py_ssize_t index, _NodeBase element not None):
+    def __setitem__(self, Py_ssize_t index, _Element element not None):
         """Replaces the given subelement.
         """
         cdef xmlNode* c_node
@@ -709,7 +456,7 @@
         """
         cdef xmlNode* c_node
         cdef xmlNode* c_next
-        cdef _Element mynode
+        cdef _Element element
         # first, find start of slice
         if start == python.PY_SSIZE_T_MAX:
             c_node = NULL
@@ -724,18 +471,18 @@
                 _appendChild(self, element)
             return
         # if the next element is in the list, insert before it
-        for mynode in value:
-            if mynode is None:
+        for element in value:
+            if element is None:
                 raise TypeError, "Node must not be None."
             # store possible text tail
-            c_next = mynode._c_node.next
+            c_next = element._c_node.next
             # now move node previous to insertion point
-            tree.xmlUnlinkNode(mynode._c_node)
-            tree.xmlAddPrevSibling(c_node, mynode._c_node)
+            tree.xmlUnlinkNode(element._c_node)
+            tree.xmlAddPrevSibling(c_node, element._c_node)
             # and move tail just behind his node
-            _moveTail(c_next, mynode._c_node)
+            _moveTail(c_next, element._c_node)
             # move it into a new document
-            moveNodeToDocument(mynode, self._doc)
+            moveNodeToDocument(element, self._doc)
 
     def __deepcopy__(self, memo):
         return self.__copy__()
@@ -987,9 +734,9 @@
 
     def __contains__(self, element):
         cdef xmlNode* c_node
-        if not isinstance(element, _NodeBase):
+        if not isinstance(element, _Element):
             return 0
-        c_node = (<_NodeBase>element)._c_node
+        c_node = (<_Element>element)._c_node
         return c_node is not NULL and c_node.parent is self._c_node
 
     def __iter__(self):
@@ -1235,6 +982,7 @@
     result._init()
     return result
 
+
 cdef class __ContentOnlyElement(_Element):
     cdef int _raiseImmutable(self) except -1:
         raise TypeError, "this element does not have children or attributes"
@@ -1321,9 +1069,263 @@
         else:
             return "<?%s?>" % self.target
 
+
+cdef public class _ElementTree [ type LxmlElementTreeType,
+                                 object LxmlElementTree ]:
+    cdef _Document _doc
+    cdef _Element _context_node
+
+    # Note that _doc is only used to store the original document if we do not
+    # have a _context_node.  All methods should prefer self._context_node._doc
+    # to honour tree restructuring.  _doc can happily be None!
+
+    cdef _assertHasRoot(self):
+        """We have to take care here: the document may not have a root node!
+        This can happen if ElementTree() is called without any argument and
+        the caller 'forgets' to call parse() afterwards, so this is a bug in
+        the caller program.
+        """
+        assert self._context_node is not None, \
+               "ElementTree not initialized, missing root"
+
+    def parse(self, source, _BaseParser parser=None):
+        """Updates self with the content of source and returns its root
+        """
+        cdef _Document doc
+        doc = _parseDocument(source, parser)
+        self._context_node = doc.getroot()
+        if self._context_node is None:
+            self._doc = doc
+        else:
+            self._doc = None
+        return self._context_node
+
+    def getroot(self):
+        """Gets the root element for this tree.
+        """
+        return self._context_node
+
+    def __copy__(self):
+        return ElementTree(self._context_node)
+
+    def __deepcopy__(self, memo):
+        if self._context_node is None:
+            return ElementTree()
+        else:
+            return ElementTree( self._context_node.__copy__() )
+
+    property docinfo:
+        """Information about the document provided by parser and DTD.  This
+        value is only defined for ElementTree objects based on the root node
+        of a parsed document (e.g.  those returned by the parse functions).
+        """
+        def __get__(self):
+            self._assertHasRoot()
+            return DocInfo(self._context_node._doc)
+
+    property parser:
+        """The parser that was used to parse the document in this ElementTree.
+        """
+        def __get__(self):
+            if self._context_node is not None and \
+                   self._context_node._doc is not None:
+                return self._context_node._doc._parser
+            return None
+
+    def write(self, file, encoding=None,
+              pretty_print=False, xml_declaration=None):
+        """Write the tree to a file or file-like object.
+        
+        Defaults to ASCII encoding and writing a declaration as needed.
+        """
+        cdef int c_write_declaration
+        self._assertHasRoot()
+        # suppress decl. in default case (purely for ElementTree compatibility)
+        if xml_declaration is not None:
+            c_write_declaration = bool(xml_declaration)
+            if encoding is None:
+                encoding = 'ASCII'
+        elif encoding is None:
+            encoding = 'ASCII'
+            c_write_declaration = 0
+        else:
+            encoding = encoding.upper()
+            c_write_declaration = encoding not in \
+                                  ('US-ASCII', 'ASCII', 'UTF8', 'UTF-8')
+        _tofilelike(file, self._context_node, encoding,
+                    c_write_declaration, bool(pretty_print))
+
+    def getpath(self, _Element element not None):
+        """Returns a structural, absolute XPath expression to find that element.
+        """
+        cdef _Document doc
+        cdef xmlDoc* c_doc
+        cdef char* c_path
+        doc = self._context_node._doc
+        if element._doc is not doc:
+            raise ValueError, "Element is not in this tree."
+        c_doc = _fakeRootDoc(doc._c_doc, self._context_node._c_node)
+        c_path = tree.xmlGetNodePath(element._c_node)
+        _destroyFakeDoc(doc._c_doc, c_doc)
+        if c_path is NULL:
+            raise LxmlError, "Error creating node path."
+        path = c_path
+        tree.xmlFree(c_path)
+        return path
+
+    def getiterator(self, tag=None):
+        """Creates an iterator for the root element. The iterator loops over all elements
+        in this tree, in document order.
+        """
+        root = self.getroot()
+        if root is None:
+            return ()
+        return root.getiterator(tag)
+
+    def find(self, path):
+        """Finds the first toplevel element with given tag. Same as getroot().find(path).
+        """
+        self._assertHasRoot()
+        root = self.getroot()
+        if path[:1] == "/":
+            path = "." + path
+        return root.find(path)
+
+    def findtext(self, path, default=None):
+        """Finds the element text for the first toplevel element with given tag. Same as getroot().findtext(path)
+        """
+        self._assertHasRoot()
+        root = self.getroot()
+        if path[:1] == "/":
+            path = "." + path
+        return root.findtext(path, default)
+
+    def findall(self, path):
+        """Finds all toplevel elements with the given tag. Same as getroot().findall(path).
+        """
+        self._assertHasRoot()
+        root = self.getroot()
+        if path[:1] == "/":
+            path = "." + path
+        return root.findall(path)
+    
+    # extensions to ElementTree API
+    def xpath(self, _path, namespaces=None, extensions=None, **_variables):
+        """XPath evaluate in context of document.
+
+        ``namespaces`` is an optional dictionary with prefix to namespace URI
+        mappings, used by XPath.  ``extensions`` defines additional extension
+        functions.
+        
+        Returns a list (nodeset), or bool, float or string.
+
+        In case of a list result, return Element for element nodes,
+        string for text and attribute values.
+
+        Note: if you are going to apply multiple XPath expressions
+        against the same document, it is more efficient to use
+        XPathEvaluator directly.
+        """
+        self._assertHasRoot()
+        evaluator = XPathDocumentEvaluator(self, namespaces, extensions)
+        return evaluator.evaluate(_path, **_variables)
+
+    def xslt(self, _xslt, extensions=None, access_control=None, **_kw):
+        """Transform this document using other document.
+
+        xslt is a tree that should be XSLT
+        keyword parameters are XSLT transformation parameters.
+
+        Returns the transformed tree.
+
+        Note: if you are going to apply the same XSLT stylesheet against
+        multiple documents, it is more efficient to use the XSLT
+        class directly.
+        """
+        self._assertHasRoot()
+        style = XSLT(_xslt, extensions=extensions,
+                     access_control=access_control)
+        return style(self, **_kw)
+
+    def relaxng(self, relaxng):
+        """Validate this document using other document.
+
+        relaxng is a tree that should contain Relax NG XML
+
+        Returns True or False, depending on whether validation
+        succeeded.
+
+        Note: if you are going to apply the same Relax NG schema against
+        multiple documents, it is more efficient to use the RelaxNG
+        class directly.
+        """
+        self._assertHasRoot()
+        schema = RelaxNG(relaxng)
+        return schema.validate(self)
+
+    def xmlschema(self, xmlschema):
+        """Validate this document using other document.
+
+        xmlschema is a tree that should contain XML Schema XML.
+
+        Returns True or False, depending on whether validation
+        succeeded.
+
+        Note: If you are going to apply the same XML Schema against
+        multiple documents, it is more efficient to use the XMLSchema
+        class directly.
+        """
+        self._assertHasRoot()
+        schema = XMLSchema(xmlschema)
+        return schema.validate(self)
+
+    def xinclude(self):
+        """Process the XInclude nodes in this document and include the
+        referenced XML fragments.
+        """
+        cdef int result
+        # We cannot pass the XML_PARSE_NOXINCNODE option as this would free
+        # the XInclude nodes - there may still be Python references to them!
+        # Therefore, we allow XInclude nodes to be converted to
+        # XML_XINCLUDE_START nodes.  XML_XINCLUDE_END nodes are added as
+        # siblings.  Tree traversal will simply ignore them as they are not
+        # typed as elements.  The included fragment is added between the two,
+        # i.e. as a sibling, which does not conflict with traversal.
+        self._assertHasRoot()
+        if self._context_node._doc._parser != None:
+            result = xinclude.xmlXIncludeProcessTreeFlags(
+                self._context_node._c_node,
+                self._context_node._doc._parser._parse_options)
+        else:
+            result = xinclude.xmlXIncludeProcessTree(
+                self._context_node._c_node)
+        if result == -1:
+            raise XIncludeError, "XInclude processing failed"
+
+    def write_c14n(self, file):
+        """C14N write of document. Always writes UTF-8.
+        """
+        self._assertHasRoot()
+        _tofilelikeC14N(file, self._context_node)
+
+cdef _ElementTree _elementTreeFactory(_Document doc, _Element context_node):
+    return _newElementTree(doc, context_node, _ElementTree)
+
+cdef _ElementTree _newElementTree(_Document doc, _Element context_node,
+                                  object baseclass):
+    cdef _ElementTree result
+    result = baseclass()
+    if context_node is None and doc is not None:
+            context_node = doc.getroot()
+    if context_node is None:
+        result._doc = doc
+    result._context_node = context_node
+    return result
+
+
 cdef class _Attrib:
-    cdef _NodeBase _element
-    def __init__(self, _NodeBase element not None):
+    cdef _Element _element
+    def __init__(self, _Element element not None):
         self._element = element
 
     # MANIPULATORS
@@ -1479,12 +1481,12 @@
 cdef public class _ElementIterator(_ElementTagMatcher) [
     object LxmlElementIterator, type LxmlElementIteratorType ]:
     # we keep Python references here to control GC
-    cdef _NodeBase _node
+    cdef _Element _node
     cdef _node_to_node_function _next_element
     def __iter__(self):
         return self
 
-    cdef void _storeNext(self, _NodeBase node):
+    cdef void _storeNext(self, _Element node):
         cdef xmlNode* c_node
         c_node = self._next_element(node._c_node)
         while c_node is not NULL and \
@@ -1498,7 +1500,7 @@
 
     def __next__(self):
         cdef xmlNode* c_node
-        cdef _NodeBase current_node
+        cdef _Element current_node
         # Python ref:
         current_node = self._node
         if current_node is None:
@@ -1508,7 +1510,7 @@
 
 cdef class ElementChildIterator(_ElementIterator):
     "Iterates over the children of an element."
-    def __init__(self, _NodeBase node not None, reversed=False, tag=None):
+    def __init__(self, _Element node not None, reversed=False, tag=None):
         cdef xmlNode* c_node
         self._initTagMatch(tag)
         if reversed:
@@ -1530,7 +1532,7 @@
 
     You can pass the boolean keyword ``preceding`` to specify the direction.
     """
-    def __init__(self, _NodeBase node not None, preceding=False, tag=None):
+    def __init__(self, _Element node not None, preceding=False, tag=None):
         self._initTagMatch(tag)
         if preceding:
             self._next_element = _previousElement
@@ -1540,7 +1542,7 @@
 
 cdef class AncestorsIterator(_ElementIterator):
     "Iterates over the ancestors of an element (from parent to parent)."
-    def __init__(self, _NodeBase node not None, tag=None):
+    def __init__(self, _Element node not None, tag=None):
         self._initTagMatch(tag)
         self._next_element = _parentElement
         self._storeNext(node)
@@ -1560,9 +1562,9 @@
     """
     # we keep Python references here to control GC
     # keep next node to return and a depth counter in the tree
-    cdef _NodeBase _next_node
-    cdef _NodeBase _top_node
-    def __init__(self, _NodeBase node not None, tag=None, inclusive=True):
+    cdef _Element _next_node
+    cdef _Element _top_node
+    def __init__(self, _Element node not None, tag=None, inclusive=True):
         self._top_node  = node
         self._next_node = node
         self._initTagMatch(tag)
@@ -1577,7 +1579,7 @@
 
     def __next__(self):
         cdef xmlNode* c_node
-        cdef _NodeBase current_node
+        cdef _Element current_node
         current_node = self._next_node
         if current_node is None:
             raise StopIteration
@@ -1729,7 +1731,7 @@
     """
     return isinstance(element, _Element)
 
-def dump(_NodeBase elem not None, pretty_print=True):
+def dump(_Element elem not None, pretty_print=True):
     """Writes an element tree or element structure to sys.stdout. This function
     should be used for debugging only.
     """
@@ -1761,8 +1763,8 @@
     else:
         write_declaration = bool(xml_declaration)
 
-    if isinstance(element_or_tree, _NodeBase):
-        return _tostring(<_NodeBase>element_or_tree,
+    if isinstance(element_or_tree, _Element):
+        return _tostring(<_Element>element_or_tree,
                          encoding, write_declaration, c_pretty_print)
     elif isinstance(element_or_tree, _ElementTree):
         return _tostring((<_ElementTree>element_or_tree)._context_node,
@@ -1782,8 +1784,8 @@
     """
     cdef int c_pretty_print
     c_pretty_print = bool(pretty_print)
-    if isinstance(element_or_tree, _NodeBase):
-        return _tounicode(<_NodeBase>element_or_tree, c_pretty_print)
+    if isinstance(element_or_tree, _Element):
+        return _tounicode(<_Element>element_or_tree, c_pretty_print)
     elif isinstance(element_or_tree, _ElementTree):
         return _tounicode((<_ElementTree>element_or_tree)._context_node,
                           c_pretty_print)

Modified: lxml/trunk/src/lxml/etreepublic.pxd
==============================================================================
--- lxml/trunk/src/lxml/etreepublic.pxd	(original)
+++ lxml/trunk/src/lxml/etreepublic.pxd	Wed Feb 14 15:19:02 2007
@@ -27,13 +27,10 @@
     cdef class lxml.etree._Document [ object LxmlDocument ]:
         cdef tree.xmlDoc* _c_doc
 
-    cdef class lxml.etree._NodeBase [ object LxmlNodeBase ]:
+    cdef class lxml.etree._Element [ object LxmlElement ]:
         cdef _Document _doc
         cdef tree.xmlNode* _c_node
 
-    cdef class lxml.etree._Element(_NodeBase) [ object LxmlElement ]:
-        pass
-
     cdef class lxml.etree.ElementBase(_Element) [ object LxmlElementBase ]:
         pass
 
@@ -56,10 +53,10 @@
     cdef _Element elementFactory(_Document doc, tree.xmlNode* c_node)
 
     # create an ElementTree for an Element
-    cdef _ElementTree elementTreeFactory(_NodeBase context_node)
+    cdef _ElementTree elementTreeFactory(_Element context_node)
 
     # create an ElementTree subclass for an Element
-    cdef _ElementTree newElementTree(_NodeBase context_node, object subclass)
+    cdef _ElementTree newElementTree(_Element context_node, object subclass)
 
     # create a new Element for an existing or new document (doc = None)
     # builds Python object after setting text, tail, namespaces and attributes
@@ -101,7 +98,7 @@
                                          char* c_ns, char* c_name)
 
     # return the value of attribute "{ns}name", or the default value
-    cdef object getAttributeValue(_NodeBase element, key, default)
+    cdef object getAttributeValue(_Element element, key, default)
 
     # return an iterator over attribute names (1), values (2) or items (3)
     # attributes must not be removed during iteration!
@@ -109,11 +106,11 @@
 
     # set an attribute value on an element
     # on failure, sets an exception and returns -1
-    cdef int setAttributeValue(_NodeBase element, key, value) except -1
+    cdef int setAttributeValue(_Element element, key, value) except -1
 
     # delete an attribute
     # on failure, sets an exception and returns -1
-    cdef int delAttribute(_NodeBase element, key) except -1
+    cdef int delAttribute(_Element element, key) except -1
 
     # delete an attribute based on name and namespace URI
     # returns -1 if the attribute was not found (no exception)
@@ -153,12 +150,12 @@
 
     cdef class lxml.etree._ElementIterator(_ElementTagMatcher) [
         object LxmlElementIterator ]:
-        cdef _NodeBase _node
+        cdef _Element _node
         cdef tree.xmlNode* (*_next_element)(tree.xmlNode*)
 
     # store the initial node of the iterator if it matches the required tag
     # or its next matching sibling if not
-    cdef void iteratorStoreNext(_ElementIterator iterator, _NodeBase node)
+    cdef void iteratorStoreNext(_ElementIterator iterator, _Element node)
 
     ##########################################################################
     # other helper functions
@@ -205,4 +202,4 @@
     cdef _Document documentOrRaise(object input)
 
     # find the root Element of an Element (itself!), ElementTree or Document
-    cdef _NodeBase rootNodeOrRaise(object input)
+    cdef _Element rootNodeOrRaise(object input)

Modified: lxml/trunk/src/lxml/extensions.pxi
==============================================================================
--- lxml/trunk/src/lxml/extensions.pxi	(original)
+++ lxml/trunk/src/lxml/extensions.pxi	Wed Feb 14 15:19:02 2007
@@ -196,16 +196,16 @@
         functions would be reference counted too soon, during the XPath
         evaluation.  This is most important in the case of exceptions.
         """
-        cdef _NodeBase element
-        if isinstance(obj, _NodeBase):
+        cdef _Element element
+        if isinstance(obj, _Element):
             self._temp_refs.add(obj)
-            self._temp_refs.add((<_NodeBase>obj)._doc)
+            self._temp_refs.add((<_Element>obj)._doc)
             return
         elif _isString(obj) or not python.PySequence_Check(obj):
             return
         for o in obj:
-            if isinstance(o, _NodeBase):
-                element = <_NodeBase>o
+            if isinstance(o, _Element):
+                element = <_Element>o
                 #print "Holding element:", <int>element._c_node
                 self._temp_refs.add(element)
                 #print "Holding document:", <int>element._doc._c_doc
@@ -245,7 +245,7 @@
 
 cdef xpath.xmlXPathObject* _wrapXPathObject(object obj) except NULL:
     cdef xpath.xmlNodeSet* resultSet
-    cdef _NodeBase node
+    cdef _Element node
     if python.PyUnicode_Check(obj):
         obj = _utf8(obj)
     if python.PyString_Check(obj):
@@ -256,13 +256,13 @@
         return xpath.xmlXPathNewFloat(obj)
     if obj is None:
         resultSet = xpath.xmlXPathNodeSetCreate(NULL)
-    elif isinstance(obj, _NodeBase):
-        resultSet = xpath.xmlXPathNodeSetCreate((<_NodeBase>obj)._c_node)
+    elif isinstance(obj, _Element):
+        resultSet = xpath.xmlXPathNodeSetCreate((<_Element>obj)._c_node)
     elif python.PySequence_Check(obj):
         resultSet = xpath.xmlXPathNodeSetCreate(NULL)
         for element in obj:
-            if isinstance(element, _NodeBase):
-                node = <_NodeBase>element
+            if isinstance(element, _Element):
+                node = <_Element>element
                 xpath.xmlXPathNodeSetAdd(resultSet, node._c_node)
             else:
                 xpath.xmlXPathFreeNodeSet(resultSet)
@@ -356,7 +356,7 @@
 
 cdef void _extension_function_call(_BaseContext context, function,
                                    xpath.xmlXPathParserContext* ctxt, int nargs):
-    cdef _NodeBase node
+    cdef _Element node
     cdef _Document doc
     cdef xpath.xmlXPathObject* obj
     cdef int i

Modified: lxml/trunk/src/lxml/iterparse.pxi
==============================================================================
--- lxml/trunk/src/lxml/iterparse.pxi	(original)
+++ lxml/trunk/src/lxml/iterparse.pxi	Wed Feb 14 15:19:02 2007
@@ -330,7 +330,7 @@
     cdef char*  _tag_name
 
     def __init__(self, element_or_tree, events=("end",), tag=None):
-        cdef _NodeBase root
+        cdef _Element root
         cdef int ns_count
         root = _rootNodeOrRaise(element_or_tree)
         self._event_filter = _buildIterparseEventFilter(events)
@@ -369,8 +369,8 @@
         return self
 
     def __next__(self):
-        cdef _NodeBase node
-        cdef _NodeBase next_node
+        cdef _Element node
+        cdef _Element next_node
         cdef int ns_count
         if python.PyList_GET_SIZE(self._events):
             return self._pop_event(0)
@@ -406,7 +406,7 @@
                 return self._pop_event(0)
         raise StopIteration
 
-    cdef int _start_node(self, _NodeBase node):
+    cdef int _start_node(self, _Element node):
         cdef int ns_count
         if self._event_filter & ITERPARSE_FILTER_START_NS:
             ns_count = _appendStartNsEvents(node._c_node, self._events)
@@ -420,8 +420,8 @@
                 python.PyList_Append(self._events, ("start", node))
         return ns_count
 
-    cdef _NodeBase _end_node(self):
-        cdef _NodeBase node
+    cdef _Element _end_node(self):
+        cdef _Element node
         node, ns_count = self._pop_node()
         if self._event_filter & ITERPARSE_FILTER_END:
             if self._tag_tuple is None or \

Modified: lxml/trunk/src/lxml/proxy.pxi
==============================================================================
--- lxml/trunk/src/lxml/proxy.pxi	(original)
+++ lxml/trunk/src/lxml/proxy.pxi	Wed Feb 14 15:19:02 2007
@@ -4,19 +4,19 @@
 # structure of the respective node to avoid multiple instantiation of
 # the Python class
 
-cdef _NodeBase getProxy(xmlNode* c_node):
+cdef _Element getProxy(xmlNode* c_node):
     """Get a proxy for a given node.
     """
     #print "getProxy for:", <int>c_node
     if c_node is not NULL and c_node._private is not NULL:
-        return <_NodeBase>c_node._private
+        return <_Element>c_node._private
     else:
         return None
 
 cdef int hasProxy(xmlNode* c_node):
     return c_node._private is not NULL
     
-cdef registerProxy(_NodeBase proxy):
+cdef registerProxy(_Element proxy):
     """Register a proxy and type for the node it's proxying for.
     """
     cdef xmlNode* c_node
@@ -28,7 +28,7 @@
     assert c_node._private is NULL, "double registering proxy!"
     c_node._private = <void*>proxy
 
-cdef unregisterProxy(_NodeBase proxy):
+cdef unregisterProxy(_Element proxy):
     """Unregister a proxy for the node it's proxying for.
     """
     cdef xmlNode* c_node
@@ -154,14 +154,14 @@
     c_node = c_doc.children
     tree.BEGIN_FOR_EACH_ELEMENT_FROM(<xmlNode*>c_doc, c_node, 1)
     if c_node._private is not NULL:
-        (<_NodeBase>c_node._private)._c_node = NULL
+        (<_Element>c_node._private)._c_node = NULL
     tree.END_FOR_EACH_ELEMENT_FROM(c_node)
     tree.xmlFreeDoc(c_doc)
 
 ################################################################################
 # change _Document references when a node changes documents
 
-cdef void moveNodeToDocument(_NodeBase node, _Document doc):
+cdef void moveNodeToDocument(_Element node, _Document doc):
     """For a node and all nodes below, change document.
 
     A node can change document in certain operations as an XML
@@ -185,5 +185,5 @@
     c_node = c_parent.children
     tree.BEGIN_FOR_EACH_ELEMENT_FROM(c_parent, c_node, 1)
     if c_node._private is not NULL:
-        (<_NodeBase>c_node._private)._doc = doc
+        (<_Element>c_node._private)._doc = doc
     tree.END_FOR_EACH_ELEMENT_FROM(c_node)

Modified: lxml/trunk/src/lxml/public-api.pxi
==============================================================================
--- lxml/trunk/src/lxml/public-api.pxi	(original)
+++ lxml/trunk/src/lxml/public-api.pxi	Wed Feb 14 15:19:02 2007
@@ -6,10 +6,10 @@
     c_node = _copyNodeToDoc(c_root, doc._c_doc)
     return _elementFactory(doc, c_node)
 
-cdef public _ElementTree elementTreeFactory(_NodeBase context_node):
+cdef public _ElementTree elementTreeFactory(_Element context_node):
     return newElementTree(context_node, _ElementTree)
 
-cdef public _ElementTree newElementTree(_NodeBase context_node,
+cdef public _ElementTree newElementTree(_Element context_node,
                                         object subclass):
     if <void*>context_node is NULL or context_node is None:
         raise TypeError
@@ -47,7 +47,7 @@
 cdef public _Document documentOrRaise(object input):
     return _documentOrRaise(input)
 
-cdef public _NodeBase rootNodeOrRaise(object input):
+cdef public _Element rootNodeOrRaise(object input):
     return _rootNodeOrRaise(input)
 
 cdef public object textOf(xmlNode* c_node):
@@ -77,16 +77,16 @@
                                             char* ns, char* name):
     return _attributeValueFromNsName(c_element, ns, name)
 
-cdef public object getAttributeValue(_NodeBase element, key, default):
+cdef public object getAttributeValue(_Element element, key, default):
     return _getAttributeValue(element, key, default)
 
 cdef public object iterattributes(_Element element, int keysvalues):
     return _attributeIteratorFactory(element, keysvalues)
 
-cdef public int setAttributeValue(_NodeBase element, key, value) except -1:
+cdef public int setAttributeValue(_Element element, key, value) except -1:
     return _setAttributeValue(element, key, value)
 
-cdef public int delAttribute(_NodeBase element, key) except -1:
+cdef public int delAttribute(_Element element, key) except -1:
     return _delAttribute(element, key)
 
 cdef public int delAttributeFromNsName(tree.xmlNode* c_element,
@@ -128,7 +128,7 @@
 cdef public object namespacedNameFromNsName(char* href, char* name):
     return _namespacedNameFromNsName(href, name)
 
-cdef public void iteratorStoreNext(_ElementIterator iterator, _NodeBase node):
+cdef public void iteratorStoreNext(_ElementIterator iterator, _Element node):
     iterator._storeNext(node)
 
 cdef public void initTagMatch(_ElementTagMatcher matcher, tag):

Modified: lxml/trunk/src/lxml/relaxng.pxi
==============================================================================
--- lxml/trunk/src/lxml/relaxng.pxi	(original)
+++ lxml/trunk/src/lxml/relaxng.pxi	Wed Feb 14 15:19:02 2007
@@ -20,7 +20,7 @@
     cdef relaxng.xmlRelaxNG* _c_schema
     def __init__(self, etree=None, file=None):
         cdef _Document doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
         cdef xmlNode* c_node
         cdef xmlDoc* fake_c_doc
         cdef char* c_href
@@ -76,7 +76,7 @@
         Returns true if document is valid, false if not."""
         cdef python.PyThreadState* state
         cdef _Document doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
         cdef xmlDoc* c_doc
         cdef relaxng.xmlRelaxNGValidCtxt* valid_ctxt
         cdef int ret

Modified: lxml/trunk/src/lxml/serializer.pxi
==============================================================================
--- lxml/trunk/src/lxml/serializer.pxi	(original)
+++ lxml/trunk/src/lxml/serializer.pxi	Wed Feb 14 15:19:02 2007
@@ -1,6 +1,6 @@
 # XML serialization and output functions
 
-cdef _tostring(_NodeBase element, encoding,
+cdef _tostring(_Element element, encoding,
                int write_xml_declaration, int pretty_print):
     "Serialize an element to an encoded string representation of its XML tree."
     cdef python.PyThreadState* state
@@ -43,7 +43,7 @@
         tree.xmlOutputBufferClose(c_buffer)
     return result
 
-cdef _tounicode(_NodeBase element, int pretty_print):
+cdef _tounicode(_Element element, int pretty_print):
     "Serialize an element to the Python unicode representation of its XML tree."
     cdef python.PyThreadState* state
     cdef tree.xmlOutputBuffer* c_buffer
@@ -146,7 +146,7 @@
 cdef int _closeFilelikeWriter(void* ctxt):
     return (<_FilelikeWriter>ctxt).close()
 
-cdef _tofilelike(f, _NodeBase element, encoding,
+cdef _tofilelike(f, _Element element, encoding,
                  int write_xml_declaration, int pretty_print):
     cdef python.PyThreadState* state
     cdef _FilelikeWriter writer
@@ -185,7 +185,7 @@
     else:
         writer._exc_context._raise_if_stored()
 
-cdef _tofilelikeC14N(f, _NodeBase element):
+cdef _tofilelikeC14N(f, _Element element):
     cdef python.PyThreadState* state
     cdef _FilelikeWriter writer
     cdef tree.xmlOutputBuffer* c_buffer

Modified: lxml/trunk/src/lxml/xmlid.pxi
==============================================================================
--- lxml/trunk/src/lxml/xmlid.pxi	(original)
+++ lxml/trunk/src/lxml/xmlid.pxi	Wed Feb 14 15:19:02 2007
@@ -22,7 +22,7 @@
     Note that you must not modify the XML tree if you use the ID dictionary.
     The results are undefined.
     """
-    cdef _NodeBase root
+    cdef _Element root
     root = XML(text)
     # xml:id spec compatible implementation: use DTD ID attributes from libxml2
     if root._doc._c_doc.ids is NULL:

Modified: lxml/trunk/src/lxml/xmlschema.pxi
==============================================================================
--- lxml/trunk/src/lxml/xmlschema.pxi	(original)
+++ lxml/trunk/src/lxml/xmlschema.pxi	Wed Feb 14 15:19:02 2007
@@ -19,7 +19,7 @@
     cdef xmlschema.xmlSchema* _c_schema
     def __init__(self, etree=None, file=None):
         cdef _Document doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
         cdef xmlDoc* fake_c_doc
         cdef xmlNode* c_node
         cdef char* c_href
@@ -72,7 +72,7 @@
         cdef python.PyThreadState* state
         cdef xmlschema.xmlSchemaValidCtxt* valid_ctxt
         cdef _Document doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
         cdef xmlDoc* c_doc
         cdef int ret
 

Modified: lxml/trunk/src/lxml/xpath.pxi
==============================================================================
--- lxml/trunk/src/lxml/xpath.pxi	(original)
+++ lxml/trunk/src/lxml/xpath.pxi	Wed Feb 14 15:19:02 2007
@@ -122,7 +122,7 @@
     XPath evaluators must not be shared between threads.
     """
     cdef _Element _element
-    def __init__(self, _NodeBase element not None, namespaces=None, extensions=None):
+    def __init__(self, _Element element not None, namespaces=None, extensions=None):
         cdef xpath.xmlXPathContext* xpathCtxt
         cdef int ns_register_status
         cdef _Document doc
@@ -253,7 +253,7 @@
         cdef xpath.xmlXPathContext* xpathCtxt
         cdef xpath.xmlXPathObject*  xpathObj
         cdef _Document document
-        cdef _NodeBase element
+        cdef _Element element
         cdef _XPathContext context
 
         document = _documentOrRaise(_etree_or_element)

Modified: lxml/trunk/src/lxml/xslt.pxi
==============================================================================
--- lxml/trunk/src/lxml/xslt.pxi	(original)
+++ lxml/trunk/src/lxml/xslt.pxi	Wed Feb 14 15:19:02 2007
@@ -279,7 +279,7 @@
         cdef xmlDoc* c_doc
         cdef xmlDoc* fake_c_doc
         cdef _Document doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
 
         doc = _documentOrRaise(xslt_input)
         root_node = _rootNodeOrRaise(xslt_input)
@@ -341,7 +341,7 @@
         cdef python.PyThreadState* state
         cdef _XSLTContext context
         cdef _Document input_doc
-        cdef _NodeBase root_node
+        cdef _Element root_node
         cdef _Document result_doc
         cdef _Document profile_doc
         cdef xmlDoc* c_profile_doc


More information about the lxml-checkins mailing list