ElementTree.XML(string XML) and ElementTree.fromstring(string XML) not working

Carl Banks pavlovevidence at gmail.com
Fri Jun 26 05:04:08 CEST 2009

On Jun 25, 6:02 pm, Kee Nethery <k... at kagi.com> wrote:
> Summary: I have XML as string and I want to pull it into ElementTree  
> so that I can play with it but it is not working for me. XML and  
> fromstring when used with a string do not do the same thing as parse  
> does with a file. How do I get this to work?
> Details:
> I have a CGI that receives XML via an HTTP POST as a POST variable  
> named 'theXml'. The POST data is a string that the CGI receives, it is  
> not a file on a hard disk.
> The POSTed string looks like this when viewed in pretty format:
> <xml>
>         <purchase id="1" lang="en">
>                 <item id="1" productId="369369">
>                         <name>Autumn</name>
>                         <quantity>1</quantity>
>                         <price>8.46</price>
>                 </item>
>                 <javascript>YES</javascript>
>         </purchase>
>         <customer id="123456" time="1227449322">
>                 <shipping>
>                         <street>19 Any Street</street>
>                         <city>Berkeley</city>
>                         <state>California</state>
>                         <zip>12345</zip>
>                         <country>People's Republic of Berkeley</country>
>                         <name>Jon Roberts</name>
>                 </shipping>
>                 <email>ju... at shrimp.edu</email>
>         </customer>
> </xml>
> The pseudocode in Python 2.6.2 looks like:
> import xml.etree.ElementTree as et
> formPostData = cgi.FieldStorage()
> theXmlData = formPostData['theXml'].value
> theXmlDataTree = et.XML(theXmlData)
> and when this runs, theXmlDataTree is set to:
> theXmlDataTree  instance        <Element xml at 7167b0>
>         attrib  dict    {}
>         tag     str     xml
>         tail    NoneType        None
>         text    NoneType        None
> I get the same result with fromstring:
> formPostData = cgi.FieldStorage()
> theXmlData = formPostData['theXml'].value
> theXmlDataTree = et.fromstring(theXmlData)
> I can put the xml in a file and reference the file by it's URL and use:
> et.parse(urllib.urlopen(theUrl))
> and that will set theXmlDataTree to:
> theXmlDataTree  instance        <xml.etree.ElementTree.ElementTree instance at  
> 0x67cb48>
> This result I can play with. It contains all the XML.

I believe you are misunderstanding something.  et.XML and
et.fromstring return Elements, whereas et.parse returns an
ElementTree.  These are two different things; however, both of them
"contain all the XML".  In fact, an ElementTree (which is returned by
et.parse) is just a container for the root Element (returned by
et.fromstring)--and it adds no important functionality to the root
Element as far as I can tell.

Given an Element (as returned by et.XML or et.fromstring) you can pass
it to the ElementTree constructor to get an ElementTree instance.  The
following line should give you something you can "play with":

theXmlDataTree = et.ElementTree(et.fromstring(theXmlData))

Conversely, given an ElementTree (as returned bu et.parse) you can
call the getroot method to obtain the root Element, like so:

theXmlRootElement = et.parse(xmlfile).getroot()

I have no use for ElementTree instances so I always call getroot right
away and only store the root element.  You may prefer to work with
ElementTrees rather than with Elements directly, and that's perfectly
fine; just use the technique above to wrap up the root Element if you
use et.fromstring.

> Why isn't et.parse the only way to do this? Why have XML or fromstring  
> at all?

Because Fredrick Lundh wanted it that way.  Unlike most Python
libraries ElementTree is under the control of one person, which means
it was not designed or vetted by the community, which means it would
tend to have some interface quirks.  You shouldn't complain: the
library is superb compared to XML solutions like DOM.  A few minor
things should be no big deal.

Carl Banks

More information about the Python-list mailing list