Editing XML as a dictionary in python? Editing XML as a dictionary in python? xml xml

Editing XML as a dictionary in python?


This'll get you a dict minus attributes. I don't know, if this is useful to anyone. I was looking for an xml to dict solution myself, when I came up with this.

      import xml.etree.ElementTree as etreetree = etree.parse('test.xml')root = tree.getroot()def xml_to_dict(el):  d={}  if el.text:    d[el.tag] = el.text  else:    d[el.tag] = {}  children = el.getchildren()  if children:    d[el.tag] = map(xml_to_dict, children)  return d

This: http://www.w3schools.com/XML/note.xml

<note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body></note>

Would equal this:

{'note': [{'to': 'Tove'},          {'from': 'Jani'},          {'heading': 'Reminder'},          {'body': "Don't forget me this weekend!"}]}


I'm not sure if converting the info set to nested dicts first is easier. Using ElementTree, you can do this:

import xml.etree.ElementTree as ETdoc = ET.parse("template.xml")lvl1 = doc.findall("level1-name")[0]lvl1.remove(lvl1.find("leaf1")lvl1.remove(lvl1.find("leaf2")# or use del lvl1[idx]doc.write("config-new.xml")

ElementTree was designed so that you don't have to convert your XML trees to lists and attributes first, since it uses exactly that internally.

It also support as small subset of XPath.


For easy manipulation of XML in python, I like the Beautiful Soup library. It works something like this:

Sample XML File:

<root>  <level1>leaf1</level1>  <level2>leaf2</level2></root>

Python code:

from BeautifulSoup import BeautifulStoneSoup, Tag, NavigableStringsoup = BeautifulStoneSoup('config-template.xml') # get the parser for the xml filesoup.contents[0].name# u'root'

You can use the node names as methods:

soup.root.contents[0].name# u'level1'

It is also possible to use regexes:

import retags_starting_with_level = soup.findAll(re.compile('^level'))for tag in tags_starting_with_level: print tag.name# level1# level2

Adding and inserting new nodes is pretty straightforward:

# build and insert a new level with a new leaflevel3 = Tag(soup, 'level3')level3.insert(0, NavigableString('leaf3')soup.root.insert(2, level3)print soup.prettify()# <root>#  <level1>#   leaf1#  </level1>#  <level2>#   leaf2#  </level2>#  <level3>#   leaf3#  </level3># </root>