[Tutor] ElementTree, iterable container, depth of elements
street.sweeper at mailworks.org
street.sweeper at mailworks.org
Fri Mar 28 23:59:31 CET 2014
I'm trying to sort the order of elements in an xml file, mostly
to make visual inspection/comparison easier. The example xml and
code on http://effbot.org/zone/element-sort.htm get me almost
what I need, but the xml I'm working with has the element I'm
trying to sort on one level deeper.
That page's example xml:
<phonebook>
<entries>
<entry>
<name>Ned</name>
<number>555-8904</number>
</entry>
<entry>
<name>John</name>
<number>555-5782</number>
</entry>
<entry>
<name>Julius</name>
<number>555-3642</number>
</entry>
</entries>
</phonebook>
And that page's last example of code:
import xml.etree.ElementTree as ET
tree = ET.parse("data.xml")
def getkey(elem):
return elem.findtext("number")
container = tree.find("entries")
container[:] = sorted(container,key=getkey)
tree.write("new-data.xml")
I used the interactive shell to experiment a bit with that,
and I can see that 'container' in
container = tree.find("entries")
is iterable, using
for a in container:
print(a)
However, the xml I'm working with looks something like this:
<root>
<main>
<diary>
<entry>
<Date>20140325</Date>
<appointment>dentist</appointment>
</entry>
<entry>
<Date>20140324</Date>
<appointment>barber</appointment>
</entry>
</diary>
</main>
</root>
What I'd like to do is rearrange the <entry> elements within
<diary> based on the <Date> element. If I remove the <root>
level, this will work, but I'm interested in getting the code to
work without editing the file.
I look for "Date" and "diary" rather than "number" and "entries"
but when I try to process the file as-is, I get an error like
Traceback (most recent call last):
File "./xmlSort.py", line 16, in <module>
container[:] = sorted(container, key=getkey)
TypeError: 'NoneType' object is not iterable
"container[:] = sorted(container, key=getkey)" confuses me,
particularly because I don't see how the elem parameter is passed
to the getkey function.
I know if I do
root = tree.getroot()
(from the python.org ElementTree docs) it is possible to step
down through the levels of root with root[0], root[0][0], etc,
and it seems to be possible to iterate with
for i in root[0][0]:
print(i)
but trying to work root[0][0] into the code has not worked,
and tree[0] is not possible.
How can I get this code to do its work one level down in the xml?
Thanks
More information about the Tutor
mailing list