I successfully added a new node to an Element using PY's ElementTree. I now try to give it attributes, which fails, despite I'm following the tutorial.
my example xml:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<level01>
<level02>
<level03>
<level04>
<node q="3,4,5,7,8" p="zen"/>
<node q="a,s,e,o,l" p="zen"/>
</level04>
</level03>
# >> here will be the new node, called <subi/> <<
<level03>
<level04>
<node q="x,y" p="zen"/>
<node q="xxx,yyy" p="zen"/>
</level04>
</level03>
</level02>
</level01>
</xml>
The node is created like this:
subi = ETL.SubElement(root[0][0][1][0][0], 'subi')
which works, it can then be accessed via root001000 and it's tag can be read.
but I fail trying to add attributes.
I tried using the syntax I found in another thread here: (with my names ofc)
>>> myattributes = {"size": "small", "gender": "unknown"}
>>> child = ET.SubElement(parent, "child", attrib=myattributes, age="10" )
Also I tried it directly, like
subi = ETL.SubElement(root[0][0][1][0][0], 'subi', attrib={"size": "small", "gender": "unknown"})
Results are always
root[0][0][1][0][0][0].tag
'subi'
but
root[0][0][1][0][0][0].attrib
{}
I also found how lxml does it, but this does not work with elementtree
#Any keyword arguments of the form name=value that you supply to the constructor are added #to the element's attributes. For example, this code:
newReed = etree.Element('reed', pitch='440', id='a4')
#will produce an element that looks like this:
<reed pitch='440' id='a4'/>
What am I doing wrong? How can I do it right? Is there a way to make elementtree do it? Or do I have to use lxml? (which would be dispreferred) ?
The constructors for Element and SubElement include **extra , which accepts attributes as keyword arguments. This allows you to add an arbitrary number of attributes. You can also use use . set to add attributes to a pre-existing element.
To read an XML file using ElementTree, firstly, we import the ElementTree class found inside xml library, under the name ET (common convension). Then passed the filename of the xml file to the ElementTree. parse() method, to enable parsing of our xml file. Then got the root (parent tag) of our xml file using getroot().
3.2 Parsing an XML String We use the ElementTree. fromstring() method to parse an XML string. The method returns root Element directly: a subtle difference compared with the ElementTree. parse() method which returns an ElementTree object.
etree. ElementTree module implements a simple and efficient API for parsing and creating XML data. Changed in version 3.3: This module will use a fast implementation whenever available.
Isn't this you are trying to do? Assuming that subi
is your element and you can access it, you can further use ElementTree
method set
:
subi.set(attr, value)
Look here about set
method of ElementTree
: https://docs.python.org/2/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.set
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')
# <Summary><TextSummary Status="Completed" /></Summary>
Alternatively, you can use .set
to add an attribute to an element after creation.
import xml.etree.ElementTree as ET
root = ET.Element('Summary')
sub = ET.SubElement(root, 'TextSummary')
sub.set('Status', 'Completed')
# <Summary><TextSummary Status="Completed" /></Summary>
Generated XML:
<Summary>
<TextSummary Status="Completed"/>
</Summary>
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. (Suggested by German Petrov).
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With