473,231 Members | 2,013 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,231 software developers and data experts.

Advice for editing xml file using ElementTree and wxPython

I'm a computational chemist who frequently dabbles in Python. A
collaborator sent me a huge XML file that at one point was evidently
modified by a now defunct java application. A sample of this file
looks something like:

<group type="struct">
<name>Test</name>
<param type="string">
<name>File Name</name>
<cTag>fileName</cTag>
<desc>Name of the input file</desc>
<value>water</value>
</param>
<param type="int">
<name>Number of Atoms</name>
<cTag>natoms</cTag>
<desc>Number of atoms in the molecule</desc>
<value>3</value>
</param>
</group>

I've been playing around with parsing that file using the ElementTree
functions, and writing little functions to walk the tree and print
stuff out. I'd like to construct a little wxPython program to modify
the values graphically, maybe using something like a TreeCtrl widget.
I'm pretty sure I can figure out how to get the data into the widget.

- Struct
- File Name: water
- Number of Atoms: 3

etc.

What's confusing me is what I do when I shut down the gui and save the
data back to a file. What I would like to be able to do is to update
the values in the ElementTree itself, and use the .write(file)
function of the elementtree to write out the file, since that ends up
printing out something pretty much identical to the original xml file.
If I want to do this, it seems like I need to keep a connection
between the gui element and the original value in the elementtree, so
I can update it. But I'm having a hard time visualizing exactly how
this works. Can someone help me out here a bit?

If this is impossible, or too difficult, I can certainly figure out a
way to dump the XML directly from the gui itself, but I worry that
I'll mangle the XML in the process, which elementtree doesn't do (i.e.
the null operation, parsing a file with elementtree and writing it out
again doesn't change anything).

Seems like this is something that's probably pretty common, modifying
a data structure using a gui, so I'm hoping that someone has thought
about this and has some good advice about best practices here.

Thanks in advance for your time,

Rick
Dec 9 '07 #1
2 4225
On Dec 8, 8:35 pm, Rick Muller <rpmul...@gmail.comwrote:
I'm a computational chemist who frequently dabbles in Python. A
collaborator sent me a huge XML file that at one point was evidently
modified by a now defunct java application. A sample of this file
looks something like:

<group type="struct">
<name>Test</name>
<param type="string">
<name>File Name</name>
<cTag>fileName</cTag>
<desc>Name of the input file</desc>
<value>water</value>
</param>
<param type="int">
<name>Number of Atoms</name>
<cTag>natoms</cTag>
<desc>Number of atoms in the molecule</desc>
<value>3</value>
</param>
</group>
<snip>
>
Seems like this is something that's probably pretty common, modifying
a data structure using a gui, so I'm hoping that someone has thought
about this and has some good advice about best practices here.
The trick is to keep a reference to the actual ElementTree objects
as you build your TreeCtrl. Ability to store arbitrary Python object
in the TreeCtrl Item makes it easy. In an event handler modify the
original element and you are done. Do not forget to save when
closing.

If the XML file is very large you may have performance issues since
the whole parsed tree is kept in memory. Luckily the ElementTree
representation is lean.

A sample below shows the approach. It is very basic but I hope it
conveys the idea. Please note that edits to the actual tags are
ignored.

-------------------------------------------------------------------
import wx
import xml.etree.cElementTree as ET

class MainFrame(wx.Frame):
def __init__(self, fpath):
wx.Frame.__init__(self, None)
self.fpath = fpath
self.xml = ET.parse(fpath)
self.tree = wx.TreeCtrl(self,
style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS)
root = self.fillmeup()
self.tree.Expand(root)

self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEdit)

def fillmeup(self):
xml = self.xml.getroot()
tree = self.tree
root = tree.AddRoot(xml.tag)
def add(parent, elem):
for e in elem:
item = tree.AppendItem(parent, e.tag, data=None)
text = e.text.strip()
if text:
val = tree.AppendItem(item, text)
tree.SetPyData(val, e)
add(item, e)
add(root, xml)
return root

def OnEdit(self, evt):
elm = self.tree.GetPyData(evt.Item)
if elm is not None:
elm.text = evt.Label

def OnClose(self, evt):
self.xml.write(self.fpath)
self.Destroy()
if __name__=='__main__':
app = wx.App(False)
frame = MainFrame('sample.xml')
frame.Show()
app.MainLoop()
Dec 9 '07 #2
On Dec 8, 11:57 pm, Waldemar Osuch <waldemar.os...@gmail.comwrote:
On Dec 8, 8:35 pm, Rick Muller <rpmul...@gmail.comwrote:
I'm a computational chemist who frequently dabbles in Python. A
collaborator sent me a huge XML file that at one point was evidently
modified by a now defunct java application. A sample of this file
looks something like:
<group type="struct">
<name>Test</name>
<param type="string">
<name>File Name</name>
<cTag>fileName</cTag>
<desc>Name of the input file</desc>
<value>water</value>
</param>
<param type="int">
<name>Number of Atoms</name>
<cTag>natoms</cTag>
<desc>Number of atoms in the molecule</desc>
<value>3</value>
</param>
</group>

<snip>
Seems like this is something that's probably pretty common, modifying
a data structure using a gui, so I'm hoping that someone has thought
about this and has some good advice about best practices here.

The trick is to keep a reference to the actual ElementTree objects
as you build your TreeCtrl. Ability to store arbitrary Python object
in the TreeCtrl Item makes it easy. In an event handler modify the
original element and you are done. Do not forget to save when
closing.

If the XML file is very large you may have performance issues since
the whole parsed tree is kept in memory. Luckily the ElementTree
representation is lean.

A sample below shows the approach. It is very basic but I hope it
conveys the idea. Please note that edits to the actual tags are
ignored.

-------------------------------------------------------------------
import wx
import xml.etree.cElementTree as ET

class MainFrame(wx.Frame):
def __init__(self, fpath):
wx.Frame.__init__(self, None)
self.fpath = fpath
self.xml = ET.parse(fpath)
self.tree = wx.TreeCtrl(self,
style=wx.TR_HAS_BUTTONS|wx.TR_EDIT_LABELS)
root = self.fillmeup()
self.tree.Expand(root)

self.Bind(wx.EVT_CLOSE, self.OnClose)
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEdit)

def fillmeup(self):
xml = self.xml.getroot()
tree = self.tree
root = tree.AddRoot(xml.tag)
def add(parent, elem):
for e in elem:
item = tree.AppendItem(parent, e.tag, data=None)
text = e.text.strip()
if text:
val = tree.AppendItem(item, text)
tree.SetPyData(val, e)
add(item, e)
add(root, xml)
return root

def OnEdit(self, evt):
elm = self.tree.GetPyData(evt.Item)
if elm is not None:
elm.text = evt.Label

def OnClose(self, evt):
self.xml.write(self.fpath)
self.Destroy()

if __name__=='__main__':
app = wx.App(False)
frame = MainFrame('sample.xml')
frame.Show()
app.MainLoop()
This was exactly what I was looking for! Thanks very much.

Rick
Dec 9 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Stewart Midwinter | last post by:
I want to parse a file with ElementTree. My file has the following format: <!-- file population.xml --> <?xml version='1.0' encoding='utf-8'?> <population> <person><name="joe" sex="male"...
14
by: Erik Bethke | last post by:
Hello All, I am getting an error of not well-formed at the beginning of the Korean text in the second example. I am doing something wrong with how I am encoding my Korean? Do I need more of a...
3
by: dlesandrini | last post by:
I need advice about my decision to go with Replication in general. This post was placed on the Microsoft Replication newsgroup, but I really value the feedback that comes from this group as well. ...
2
by: Randall Parker | last post by:
Running Python 2.4.2 on Windows in SPE. I have a very small XML file (see below) that is in UTF-8 and saved by Windows Notepad as such. I'm reading it with minidom. My problem is that once I...
2
by: mirandacascade | last post by:
Situation is this: 1) I have inherited some python code that accepts a string object, the contents of which is an XML document, and produces a data structure that represents some of the content of...
8
by: D | last post by:
Hi, I currently have a Python app with a Tkinter GUI frontend that I use for system administration. Everytime it launches, it reads a text file which contains info about each host I wish to...
4
by: Chelonian | last post by:
I'm considering trying to learn Python for a specific reason, and hoped the group might help me get a sense for whether it would be worth my time. The situation... Me: total beginner w/ a...
0
by: limodou | last post by:
I don't know if it's a bug? Try below code: ... print 'hhhh' ... 0 You can see if I test a, the result will be False. I don't know if it's an expected result, but this thing has beaten...
11
by: Peter Pei | last post by:
One bad design about elementtree is that it has different ways parsing a string and a file, even worse they return different objects: 1) When you parse a file, you can simply call parse, which...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.