Python lxml the E-Factory
Question: I've been using the lxml "E-Factory" (aka. ElementMaker) for creating xml
documents. I'm trying to generate an xml document similar to this:

    
    
    <url>
      <date-added>2011-11-11</date-added>
    </url>
    

However, using the E-factory, I'm not sure how to specify the dash in the
'data-added' element. It seems to be interpreting the dash as a minus sign.

Here is the docs I've been referring to: <http://lxml.de/tutorial.html#the-e-
factory>

Here is how to reproduce the error:

    
    
    from lxml import etree
    from lxml.builder import ElementMaker 
    
    E = ElementMaker()
    URL = E.url
    DATE_ADDED = E.date-added
    
    xml = URL(DATE_ADDED(myobject.created.strftime('%Y-%m-%dT%H:%M:%S')),)
    
    
    NameError global name 'added' is not defined
    

Does anyone know a trick to get it do properly render the element with a dash?

Thank you for reading this.

Joe


Answer: The `ElementMaker` maps a function to a tag name (by using e.g.
`E.date_added`) to build up the XML tree. However, there is a discrepancy
between the allowed characters in HTML/XML tags and Python functions. As
stated in [PEP 8](http://www.python.org/dev/peps/pep-0008/): _"Package and
Module Names Modules should have short, all-lowercase names. Underscores can
be used in the module name if it improves readability"_. So, the `date_added`
function includes an underscore, which isn't allowed to be present in a Python
function:

    
    
    >>> def foo-bar():
      File "<stdin>", line 1
        def foo-bar():
               ^
    SyntaxError: invalid syntax
    

To resolve it, just create the `date-added` tag a bit more verbosely by
supplying the name as an argument instead:

    
    
    >>> etree.tostring(E.url(E('date-added', '2011-11-11')))
    '<url><date-added>2011-11-11</date-added></url>'
    

