Why is there no functional xml?

Peter Otten __peter__ at web.de
Sun Jan 21 06:20:36 EST 2018


Rustom Mody wrote:

> Looking around for how to create (l)xml one sees typical tutorials like
> this:
> 
> https://www.blog.pythonlibrary.org/2013/04/30/python-101-intro-to-xml-parsing-with-elementtree/
> 
> 
> 
> Given the requirement to build up this xml:
> <zAppointments reminder="15">
>     <appointment>
>         <begin>1181251680</begin>
>         <uid>040000008200E000</uid>
>         <alarmTime>1181572063</alarmTime>
>         <state></state>
>         <location></location>
>         <duration>1800</duration>
>         <subject>Bring pizza home</subject>
>     </appointment>
> </zAppointments>
> 
> 
> 
> the way I would rather do it is thus:
> 
> [Note in actual practice the 'contents' such as 1181251680 etc would come
> from suitable program variables/function-calls
> ]
> 
> 
> ex = Ea("zAppointments",  {'reminder':'15'},
>         E("appointment",
>           En("begin", 1181251680),
>           Et("uid", "040000008200E000"),
>           En("alarmTime", 1181572063),
>           E("state"),
>           E("location"),
>           En("duration",1800),
>           Et("subject", "Bring pizza home")))
> 
> 
> with the following obvious definitions:
> 
> [The function names are short so that the above becomes correspondingly
> [readable]
> 
> 
> from lxml.etree import Element
> 
> def Ea(tag, attrib=None, *subnodes):
>     "xml node constructor"
>     root = Element(tag, attrib)
>     for n in subnodes:
>         root.append(n)
>     return root
> 
> def E(tag, *subnodes):
>     "Like E but without attributes"
>     root = Element(tag)
>     for n in subnodes:
>         root.append(n)
>     return root
> 
> def Et(tag, text):
>     "A pure text node"
>     root = E(tag)
>     root.text = text
>     return root
> 
> def En(tag, text):
>     "A node containing a integer"
>     root = E(tag)
>     root.text = str(text)
>     return root
> 
> 
> This approach seems so obvious that I find it hard to believe its not
> there somewhere… Am I missing something??

lxml.objectify?

>>> from lxml import etree
>>> from lxml.objectify import E
>>> appointments = E.appointments(
...     E.appointment(
...         E.begin(1181251680),
...         E.uid("040000008200E000"),
...         E.alarmTime(1181572063),
...         E.state(),
...         E.location(),
...         E.duration(1800),
...         E.subject("Bring pizza home")
...     ),
...     reminder="15"
... )
>>> print(etree.tostring(appointments, pretty_print=True, encoding=str))
<appointments xmlns:py="http://codespeak.net/lxml/objectify/pytype" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" reminder="15">
  <appointment>
    <begin py:pytype="int">1181251680</begin>
    <uid py:pytype="str">040000008200E000</uid>
    <alarmTime py:pytype="int">1181572063</alarmTime>
    <state/>
    <location/>
    <duration py:pytype="int">1800</duration>
    <subject py:pytype="str">Bring pizza home</subject>
  </appointment>
</appointments>

>>> 

Personally I'd probably avoid the extra layer and write a function that 
directly maps dataclasses or database records to xml using the conventional 
elementtree API.






More information about the Python-list mailing list