19

I am using ElementTree to build an XML file.

When I try to set an element's attribute with ET.SubElement().__setattr__(), I get the error AttributeError: __setattr__.

import xml.etree.cElementTree as ET
summary = open(Summary.xml, 'w')
root = ET.Element('Summary')
ET.SubElement(root, 'TextSummary')
ET.SubElement(root,'TextSummary').__setattr__('Status','Completed') # Error occurs here
tree = ET.ElementTree(root) 
tree.write(summary)
summary.close()

After code execution, my XML should resemble the following:

<Summary>
    <TextSummary Status = 'Completed'/>
</Summary>

How do I add attributes to an XML element with Python using xml.etree.cElementTree?

3 Answers 3

41

You should be doing:

ET.SubElement(root,'TextSummary').set('Status','Completed')

The Etree documentation shows usage.

Sign up to request clarification or add additional context in comments.

3 Comments

Is there a way to set attributes for a root element?
@StevenVascellaro Yes: just do root.set('foo', 'bar').
17

You can specify attributes for an Element or SubElement during creation with keyword arguments.

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
ET.SubElement(root, 'TextSummary', Status='Completed')

XML:

<Summary>
    <TextSummary Status="Completed"/>
</Summary>

Alternatively, you can use .set to add attributes to an existing element.

import xml.etree.ElementTree as ET

root = ET.Element('Summary')
sub = ET.SubElement(root, 'TextSummary')
sub.set('Status', 'Completed')

XML:

<Summary>
    <TextSummary Status="Completed"/>
</Summary>

Technical Explanation:

The constructors for Element and SubElement include **extra, which accepts attributes as keyword arguments.

xml.etree.ElementTree.Element(tag, attrib={}, **extra)
xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

This allows you to add an arbitrary number of attributes.

root = ET.Element('Summary', Date='2018/07/02', Timestamp='11:44am')
# <Summary Date = "2018/07/02" Timestamp = "11:44am">

You can also use use .set to add attributes to a pre-existing element. However, this can only add one element at a time. (As suggested by Thomas Orozco).

root = ET.Element('Summary')
root.set('Date', '2018/07/02')
root.set('Timestamp', '11:44am')
# <Summary Date = "2018/07/02" Timestamp = "11:44am">

Full Example:

import xml.etree.ElementTree as ET

root = ET.Element('school', name='Willow Creek High')
ET.SubElement(root, 'student', name='Jane Doe', grade='9')
print(ET.tostring(root).decode())
# <school name="Willow Creek High"><student grade="9" name="Jane Doe" /></school>

Comments

3

The best way to set multiple attributes in single line is below. I wrote this code for SVG XML creation:

from xml.etree import ElementTree as ET

svg = ET.Element('svg', attrib={'height':'210','width':'500'})
g = ET.SubElement(svg,'g', attrib={'x':'10', 'y':'12','id':'groupName'})
line = ET.SubElement(g, 'line', attrib={'x1':'0','y1':'0','x2':'200','y2':'200','stroke':'red'})

print(ET.tostring(svg, encoding="us-ascii", method="xml"))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.