tags:

views:

1058

answers:

4

Let's say I have an existing trivial XML file named 'MyData.xml' that contains the following:

<?xml version="1.0" encoding="utf-8" ?>
<myElement>foo</myElement>

I want to change the text value of 'foo' to 'bar' resulting in the following:

<?xml version="1.0" encoding="utf-8" ?>
<myElement>bar</myElement>

Once I am done, I want to save the changes.

What is the easiest and simplest way to accomplish all this?

+3  A: 

For quick, non-critical XML manipulations, i really like P4X. It let's you write like this:

import p4x
doc = p4x.P4X (open(file).read)
doc.myElement = 'bar'
Javier
+3  A: 

Use Python's minidom

Basically you will take the following steps:

  1. Read XML data into DOM object
  2. Use DOM methods to modify the document
  3. Save new DOM object to new XML document

The python spec should hold your hand rather nicely though this process.

Ryan
So, for # 3 would I have explicitly overwrite the existing file versus using some built-in function in minidom that might implicitly do that for me?
Ray Vega
Ray: yes, any DOM manipulations will be in-memory only. You'll have to copy to a new file or overwrite the existing file. For tips on how to handle modifying an existing file, see this post: http://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python
technomalogical
@technomalogical- Thanks for clarifying that for me! Too bad I can't upvote your comment. :)
Ray Vega
+2  A: 

This is what I wrote based on @Ryan's answer:

from xml.dom.minidom import parse
import os

# create a backup of original file
new_file_name = 'MyData.xml'
old_file_name = new_file_name + "~"
os.rename(new_file_name, old_file_name)

# change text value of element
doc = parse(old_file_name)
node = doc.getElementsByTagName('myElement')
node[0].firstChild.nodeValue = 'bar'

# persist changes to new file
xml_file = open(new_file_name, "w")
doc.writexml(xml_file, encoding="utf-8")
xml_file.close()

Not sure if this was the easiest and simplest approach but it does work. (@Javier's answer has less lines of code but requires non-standard library)

Ray Vega
+1  A: 

You also might want to check out Uche Ogbuji's excellent XML Data Binding Library, Amara: http://uche.ogbuji.net/tech/4suite/amara

(Documentation here: http://platea.pntic.mec.es/~jmorilla/amara/manual/)

The cool thing about Amara is that it turns an XML document in to a Python object, so you can just do stuff like:

record = doc.xml_create_element(u'Record')

nameElem = doc.xml_create_element(u'Name', content=unicode(name))

record.xml_append(nameElem)

valueElem = doc.xml_create_element(u'Value', content=unicode(value))

record.xml_append(valueElem

(which creates a Record element that contains Name and Value elements (which in turn contain the values of the name and value variables)).

machineghost