views:

3333

answers:

6

I'm trying to generate customized xml files from a template xml file in python.

Conceptually, I want to read in the template xml, remove some elements, change some text attributes, and write the new xml out to a file. I wanted it to work something like this:

conf_base = ConvertXmlToDict('config-template.xml') conf_base_dict = conf_base.UnWrap() del conf_base_dict['root-name']['level1-name']['leaf1'] del conf_base_dict['root-name']['level1-name']['leaf2']

conf_new = ConvertDictToXml(conf_base_dict)

now I want to write to file, but I don't see how to get to ElementTree.ElementTree.write()

conf_new.write('config-new.xml')

Is there some way to do this, or can someone suggest doing this a different way?

+7  A: 

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 ET
doc = 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.

Torsten Marek
A: 

Have you tried this?

print xml.etree.ElementTree.tostring( conf_new )
S.Lott
+4  A: 

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 BeatifulStoneSoup, Tag, NavigableString

soup = BeautifulStoneSoup('config-template.xml') # get the parser for the xml file
soup.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 re
tags_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 leaf
level3 = 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>
Chris Lawlor
BeautifulSoup converts everything to lower case. That really sucks. I have to preserve the cases of tags and values!
A: 

how to remove xml tag in web site with python?

+5  A: 

This'll get you a dict minus attributes... dunno 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 etree

tree = 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

Would equal this:


{'note': [{'to': 'Tove'},
          {'from': 'Jani'},
          {'heading': 'Reminder'},
          {'body': "Don't forget me this weekend!"}]}
Daniel Anderson
very helpful for me; thanks!
mellort
A: 

most direct way to me :

root        = ET.parse(xh)
data        = root.getroot()
xdic        = {}
if data > None:
    for part in data.getchildren():
        xdic[part.tag] = part.text
Loooo