ElementTree Returns Element Instead of ElementTree

11,407

This one bit me too. I had some old code kicking around that used parse(). I refactored to use fromstring(), causing the same error. Based on your references, I can summarize what's going on here; I believe this will be beneficial for people getting this specific error. The other articles deal directly with the API itself so I wouldn't consider them duplicates.

So, first to address this point. You are correct that the stated issue is related, however I don't think the accepted answer is making the claim that fromstring() is supposed to return an ElementTree. Rather, the author of this answer is saying in the context of the problem the string is equivalent to a complete XML document rather than a fragment, so it's appropriate to convert it to an ElementTree:

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.

And in his code sample, he does just that:

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

This approach is confirmed by the second reference you posted, which links an old article by the library's author, in which he states (and I paraphrase) that this is not a design quirk, it's a feature. The expectation is that constructs like parse() are designed to work with complete documents and fromstring() is designed to work with fragments and documents. It's just in this latter case that we the programmer must resolve the ambiguity and inform the library that we expect the string to be a complete document.

So, as far as my use case goes, I had a complete document in my XML string and wanted the ElementTree features, so I wrapped my fromstring() call in an ElementTree as in the example above.

Share:
11,407
ElToro1966
Author by

ElToro1966

Experienced developer &amp; PM. Data science, DataOps, Python &amp; R. DevOps, Linux, clean code &amp; agile. Working remotely. I am a Norwegian IT professional living in Spain; experienced project manager and programmer with skills covering data science, DevOps and Linux at large. I have a particular interest in clean code and software quality in general. Functional, object-oriented and procedural paradigms. Have worked quite a lot with Python and related technologies, as well as R. Have also worked with Erlang, Javascript, Google Script and PHP (among others). Believer in the efficiency of agile development. Keen interest in concurrent technologies. I have worked in many different sectors and cultures (work- and at large). Fluent in English, Spanish and Norwegian. Work-level proficiency in Danish, French, German and Swedish. Good understanding of Portuguese and Galician. What I do for fun; cooking, books, music, motorcycles &amp; surfing. Total sci-fi fan.

Updated on June 04, 2022

Comments

  • ElToro1966
    ElToro1966 almost 2 years

    I am trying to build an ElementTree from a string. When I do the following (as set out in Python ElementTree: Parsing a string and getting ElementTree instance), I get an Element instead of an ElementTree:

    companyTree = ElementTree.ElementTree(ElementTree.fromstring('<companies></companies>'))
    

    If I do

    print(companyTree.getroot())
    

    I get

    AttributeError: 'xml.etree.ElementTree.Element' object has no attribute 'getroot'

    In other words, companyTree is an Element instead of an ElementTree. According to the accepted answer in 1, I should be getting an ElementTree. Has the API changed? How do I get an ElementTree from a string now? Thanks.

    Note that there is more on this problem in Python ElementTree: ElementTree vs root Element

  • samwyse
    samwyse almost 7 years
    Incredibly useful answer! Don't know why no other up-votes.
  • Ajay Thomas
    Ajay Thomas over 6 years
    Yes this answer saved me a lot of time. Well detailed explanation!
  • AKMalkadi
    AKMalkadi over 2 years
    I would consider your answer as the accepted answer. I hope the OP do so