[Lxml-checkins] r44661 - in lxml/branch/lxml-1.3: . doc src/lxml

scoder at codespeak.net scoder at codespeak.net
Mon Jul 2 10:55:24 CEST 2007


Author: scoder
Date: Mon Jul  2 10:55:24 2007
New Revision: 44661

Modified:
   lxml/branch/lxml-1.3/CHANGES.txt
   lxml/branch/lxml-1.3/doc/objectify.txt
   lxml/branch/lxml-1.3/src/lxml/builder.py
   lxml/branch/lxml-1.3/src/lxml/objectify.pyx
Log:
objectify: merged in E-factory support from trunk

Modified: lxml/branch/lxml-1.3/CHANGES.txt
==============================================================================
--- lxml/branch/lxml-1.3/CHANGES.txt	(original)
+++ lxml/branch/lxml-1.3/CHANGES.txt	Mon Jul  2 10:55:24 2007
@@ -11,6 +11,8 @@
 * objectify.DataElement now supports setting values from existing data
   elements (not just plain Python types) and reuses defined namespaces etc.
 
+* E-factory support for lxml.objectify (``objectify.E``)
+
 Bugs fixed
 ----------
 

Modified: lxml/branch/lxml-1.3/doc/objectify.txt
==============================================================================
--- lxml/branch/lxml-1.3/doc/objectify.txt	(original)
+++ lxml/branch/lxml-1.3/doc/objectify.txt	Mon Jul  2 10:55:24 2007
@@ -266,6 +266,45 @@
     notB
 
 
+Tree generation with the E-factory
+----------------------------------
+
+To simplify the generation of trees even further, you can use the E-factory::
+
+    >>> E = objectify.E
+    >>> root = E.root(
+    ...   E.a(5),
+    ...   E.b(6.1),
+    ...   E.c(True),
+    ...   E.d("how")
+    ... )
+
+    >>> print etree.tostring(root, pretty_print=True)
+    <root>
+      <a>5</a>
+      <b>6.1</b>
+      <c>true</c>
+      <d>how</d>
+    </root>
+
+This allows you to write up a specific language in tags::
+
+    >>> ROOT = objectify.E.root
+    >>> TITLE = objectify.E.title
+    >>> TYPE = objectify.E.type
+
+    >>> root = ROOT(
+    ...   TITLE("The title"),
+    ...   TYPE(5)
+    ... )
+
+    >>> print etree.tostring(root, pretty_print=True)
+    <root>
+      <title>The title</title>
+      <type>5</type>
+    </root>
+
+
 Namespace handling
 ------------------
 

Modified: lxml/branch/lxml-1.3/src/lxml/builder.py
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/builder.py	(original)
+++ lxml/branch/lxml-1.3/src/lxml/builder.py	Mon Jul  2 10:55:24 2007
@@ -140,7 +140,10 @@
 		elem[-1].tail = (elem[-1].tail or "") + item
 	    else:
 		elem.text = (elem.text or "") + item
-	typemap[str] = typemap[unicode] = add_text
+        if str not in typemap:
+            typemap[str] = add_text
+        if unicode not in typemap:
+            typemap[unicode] = add_text
 
 	def add_dict(elem, item):
 	    attrib = elem.attrib
@@ -149,7 +152,8 @@
 		    attrib[k] = v
 		else:
 		    attrib[k] = typemap[type(v)](None, v)
-	typemap[dict] = add_dict
+        if dict not in typemap:
+            typemap[dict] = add_dict
 
 	self._typemap = typemap
 

Modified: lxml/branch/lxml-1.3/src/lxml/objectify.pyx
==============================================================================
--- lxml/branch/lxml-1.3/src/lxml/objectify.pyx	(original)
+++ lxml/branch/lxml-1.3/src/lxml/objectify.pyx	Mon Jul  2 10:55:24 2007
@@ -65,6 +65,8 @@
 cdef object islice
 from itertools import islice
 
+cdef object _ElementMaker
+from builder import ElementMaker as _ElementMaker
 
 # namespace/name for "pytype" hint attribute
 cdef object PYTYPE_NAMESPACE
@@ -1633,6 +1635,42 @@
         parser = objectify_parser
     return _parse(f, parser)
 
+class ElementMaker(_ElementMaker):
+    def __init__(self, typemap=None):
+        if typemap is None:
+            typemap = {}
+        else:
+            typemap = typemap.copy()
+
+        typemap[__builtin__.str]     = __add_text
+        typemap[__builtin__.unicode] = __add_text
+        typemap[__builtin__.int]     = __add_text
+        typemap[__builtin__.long]    = __add_text
+        typemap[__builtin__.float]   = __add_text
+        typemap[__builtin__.bool]    = __add_text
+
+        _ElementMaker.__init__(self, typemap, objectify_parser.makeelement)
+
+def __add_text(_Element elem not None, text):
+    cdef tree.xmlNode* c_child
+    if isinstance(text, bool):
+        text = str(text).lower()
+    else:
+        text = str(text)
+    c_child = cetree.findChildBackwards(elem._c_node, 0)
+    if c_child is not NULL:
+        old = cetree.tailOf(c_child)
+        if old is not None:
+            text = old + text
+        cetree.setTailText(c_child, text)
+    else:
+        old = cetree.textOf(elem._c_node)
+        if old is not None:
+            text = old + text
+        cetree.setNodeText(elem._c_node, text)
+
+E = ElementMaker()
+
 cdef object _DEFAULT_NSMAP
 _DEFAULT_NSMAP = { "py"  : PYTYPE_NAMESPACE,
                    "xsi" : XML_SCHEMA_INSTANCE_NS,


More information about the lxml-checkins mailing list