View Single Post
Old Jun 9th, 2007, 5:03 PM   #4
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5 Arevos is on a distinguished road
Well, say you have found the element you want via the approach demonstrated above, and assigned it to the variable "sword":
python Syntax (Toggle Plain Text)
  1. # Get name element of sword
  2. name = sword.getElementsByTagName("Name")[0]
  3.  
  4. # Change text in name
  5. name.firstChild.replaceWholeText("Short Sword")
  6.  
  7. # Output the new xml
  8. print xml.toxml()
This demonstrates that one can alter the XML DOM tree in place, and then output it as XML with all the changes made.

However, this isn't a very good way of doing things. A better way would be to have a "dump" and "load" method on each class:
python Syntax (Toggle Plain Text)
  1. import xml.dom.minidom as dom
  2.  
  3. class Sword:
  4. def __init__(self, name):
  5. self.name = name
  6.  
  7. def dump(self):
  8. sword = dom.Element("Sword")
  9. name = dom.Element("Name")
  10. text = dom.Text()
  11. text.replaceWholeText(self.name)
  12. name.appendChild(text)
  13. sword.appendChild(name)
  14. return sword
  15.  
  16. @classmethod
  17. def load(self, sword_element):
  18. name = sword_element.getElementsByTagName("Name")[0]
  19. return Sword(name.firstChild.wholeText)
But we can do even better than this:
python Syntax (Toggle Plain Text)
  1. import xml.dom.minidom as dom
  2.  
  3. def todom(sexpr):
  4. if type(sexpr) is list or type(sexpr) is tuple:
  5. node = dom.Element(sexpr[0])
  6. for child in sexpr[1:]:
  7. node.appendChild(todom(child))
  8. else:
  9. node = dom.Text()
  10. node.replaceWholeText(str(sexpr))
  11. return node
The above function converts s-expressions into XML, and we can use this to considerably shorten the code of our Sword class:
python Syntax (Toggle Plain Text)
  1. class Sword:
  2. def __init__(self, name):
  3. self.name = name
  4.  
  5. def dump(self):
  6. return todom(("Sword" ("Name", self.name)))
  7.  
  8. @classmethod
  9. def load(self, sword_element):
  10. name = sword_element.getElementsByTagName("Name")[0]
  11. return Sword(name.firstChild.wholeText)
There's probably quite a few XML serialisation libraries worth looking into as well... Though I'd personally look into YAML as an alternative to storing human-editable data to file.
Arevos is offline   Reply With Quote