On Dec 8, 11:57 pm, Waldemar Osuch <[EMAIL PROTECTED]> wrote: > On Dec 8, 8:35 pm, Rick Muller <[EMAIL PROTECTED]> wrote: > > > > > 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 -- http://mail.python.org/mailman/listinfo/python-list