Python ElementTree: Parsing a string and getting ElementTree instance
Asked Answered
D

2

22

I have a string containing XML data that is returned from an http request.

I am using ElementTree to parse the data, and I want to then search recursively for an element.

According to this question, I can only search recursively with result.findall() if result is of type ElementTree rather than type Element.

Now xml.etree.ElementTree.fromstring() , used to parse the string, returns an Element object, while xml.etree.ElementTree.parse(), used to parse a file, returns an ElementTree object.

My question is then: How can I parse the string and get an ElementTree instance? (without any madness like writing to a temporary file)

Deliver answered 20/12, 2011 at 18:33 Comment(0)
P
32

When you use ElementTree.fromstring() what you're getting back is basically the root of the tree, so if you create a new tree like this ElementTree.ElementTree(root) you'll get you're looking for.

So, to make it clearer:

from xml.etree import ElementTree
tree = ElementTree.ElementTree(ElementTree.fromstring(<your_xml_string>))

or:

from xml.etree.ElementTree import fromstring, ElementTree
tree = ElementTree(fromstring(<your_xml_string>))
Pretrice answered 20/12, 2011 at 18:41 Comment(3)
I just want to add - for those using lxml - that in lxml (where an element always belongs to a document/tree, even if implicit), you can use the getrootttree() method.Accommodate
Thanks! Really annoying API design in etree, to have different types of output just depending on the input source. Really confusing :(Albi
This really isn't very clear in the documentation. "fromstring() parses XML from a string directly into an Element, which is the root element of the parsed tree. Other parsing functions may create an ElementTree."Hopfinger
U
8

Turn your string into a file-like object and use ElementTree.parse:

from xml.etree import ElementTree
from cStringIO import StringIO

tree = ElementTree.parse(StringIO(string))
Uturn answered 20/12, 2011 at 21:49 Comment(1)
Great, this is the one that I was looking for. :-)Bannerol

© 2022 - 2024 — McMap. All rights reserved.