[Lxml-checkins] r46207 - lxml/trunk/src/lxml

scoder at codespeak.net scoder at codespeak.net
Fri Aug 31 09:43:29 CEST 2007


Author: scoder
Date: Fri Aug 31 09:43:28 2007
New Revision: 46207

Modified:
   lxml/trunk/src/lxml/apihelpers.pxi
   lxml/trunk/src/lxml/etree.pyx
   lxml/trunk/src/lxml/etreepublic.pxd
   lxml/trunk/src/lxml/objectify.pyx
   lxml/trunk/src/lxml/public-api.pxi
Log:
new _makeSubElement() C-function to make the SubElement() factory available at the C level and as makeSubElement() in the public C-API

Modified: lxml/trunk/src/lxml/apihelpers.pxi
==============================================================================
--- lxml/trunk/src/lxml/apihelpers.pxi	(original)
+++ lxml/trunk/src/lxml/apihelpers.pxi	Fri Aug 31 09:43:28 2007
@@ -105,6 +105,8 @@
     elif c_doc is NULL:
         c_doc = _newDoc()
     c_node = _createElement(c_doc, name_utf)
+    if c_node is NULL:
+        return python.PyErr_NoMemory()
     try:
         if text is not None:
             _setNodeText(c_node, text)
@@ -129,6 +131,47 @@
             tree.xmlFreeDoc(c_doc)
         raise
 
+cdef _Element _makeSubElement(_Element parent, tag, text, tail,
+                              attrib, nsmap, extra_attrs):
+    """Create a new child element and initialize text content, namespaces and
+    attributes.
+
+    This helper function will reuse as much of the existing document as
+    possible:
+
+    If 'parser' is None, the parser will be inherited from 'doc' or the
+    default parser will be used.
+
+    If 'doc' is None, 'c_doc' is used to create a new _Document and the new
+    element is made its root node.
+
+    If 'c_doc' is also NULL, a new xmlDoc will be created.
+    """
+    cdef _Document doc
+    cdef xmlNode* c_node
+    cdef xmlDoc* c_doc
+    if parent is None or parent._doc is None:
+        return None
+    ns_utf, name_utf = _getNsTag(tag)
+    _tagValidOrRaise(name_utf)
+    doc = parent._doc
+    c_doc = doc._c_doc
+
+    c_node = _createElement(c_doc, name_utf)
+    if c_node is NULL:
+        return python.PyErr_NoMemory()
+    tree.xmlAddChild(parent._c_node, c_node)
+
+    if text is not None:
+        _setNodeText(c_node, text)
+    if tail is not None:
+        _setTailText(c_node, tail)
+
+    # add namespaces to node if necessary
+    doc._setNodeNamespaces(c_node, ns_utf, nsmap)
+    _initNodeAttributes(c_node, doc, attrib, extra_attrs)
+    return _elementFactory(doc, c_node)
+
 cdef _initNodeAttributes(xmlNode* c_node, _Document doc, attrib, extra):
     """Initialise the attributes of an element node.
     """

Modified: lxml/trunk/src/lxml/etree.pyx
==============================================================================
--- lxml/trunk/src/lxml/etree.pyx	(original)
+++ lxml/trunk/src/lxml/etree.pyx	Fri Aug 31 09:43:28 2007
@@ -1980,17 +1980,7 @@
     """Subelement factory.  This function creates an element instance, and
     appends it to an existing element.
     """
-    cdef xmlNode*  c_node
-    cdef _Document doc
-    ns_utf, name_utf = _getNsTag(_tag)
-    _tagValidOrRaise(name_utf)
-    doc = _parent._doc
-    c_node = _createElement(doc._c_doc, name_utf)
-    tree.xmlAddChild(_parent._c_node, c_node)
-    # add namespaces to node if necessary
-    doc._setNodeNamespaces(c_node, ns_utf, nsmap)
-    _initNodeAttributes(c_node, doc, attrib, _extra)
-    return _elementFactory(doc, c_node)
+    return _makeSubElement(_parent, _tag, None, None, attrib, nsmap, _extra)
 
 def ElementTree(_Element element=None, file=None, _BaseParser parser=None):
     """ElementTree wrapper class.

Modified: lxml/trunk/src/lxml/etreepublic.pxd
==============================================================================
--- lxml/trunk/src/lxml/etreepublic.pxd	(original)
+++ lxml/trunk/src/lxml/etreepublic.pxd	Fri Aug 31 09:43:28 2007
@@ -63,6 +63,11 @@
     cdef _Element makeElement(tag, _Document doc, parser,
                               text, tail, attrib, nsmap)
 
+    # create a new SubElement for an existing parent
+    # builds Python object after setting text, tail, namespaces and attributes
+    cdef _Element makeSubElement(_Element parent, tag, text, tail,
+                                 attrib, nsmap)
+
     # deep copy a node to include it in the Document
     cdef _Element deepcopyNodeToDocument(_Document doc, tree.xmlNode* c_root)
 

Modified: lxml/trunk/src/lxml/objectify.pyx
==============================================================================
--- lxml/trunk/src/lxml/objectify.pyx	(original)
+++ lxml/trunk/src/lxml/objectify.pyx	Fri Aug 31 09:43:28 2007
@@ -1097,13 +1097,12 @@
             elif isinstance(child, _ObjectifyElementMakerCaller):
                 elementMaker = <_ObjectifyElementMakerCaller>child
                 if elementMaker._element_factory is None:
-                    childElement = cetree.makeElement(
-                        elementMaker._tag, element._doc, objectify_parser,
-                        None, None, None, None)
+                    cetree.makeSubElement(element, elementMaker._tag,
+                                          None, None, None, None)
                 else:
                     childElement = elementMaker._element_factory(
                         elementMaker._tag)
-                cetree.appendChild(element, childElement)
+                    cetree.appendChild(element, childElement)
             else:
                 pytype = python.PyDict_GetItem(
                     _PYTYPE_DICT, _typename(child))

Modified: lxml/trunk/src/lxml/public-api.pxi
==============================================================================
--- lxml/trunk/src/lxml/public-api.pxi	(original)
+++ lxml/trunk/src/lxml/public-api.pxi	Fri Aug 31 09:43:28 2007
@@ -25,6 +25,10 @@
                                  text, tail, attrib, nsmap):
     return _makeElement(tag, NULL, doc, parser, text, tail, attrib, nsmap, None)
 
+cdef public _Element makeSubElement(_Element parent, tag, text, tail,
+                                    attrib, nsmap):
+    return _makeSubElement(parent, tag, text, tail, attrib, nsmap, None)
+
 cdef public void setElementClassLookupFunction(
     _element_class_lookup_function function, state):
     _setElementClassLookupFunction(function, state)


More information about the lxml-checkins mailing list