Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jun 8th, 2007, 2:02 PM   #1
MR.T
Newbie
 
MR.T's Avatar
 
Join Date: Feb 2006
Location: USA,Michigan
Posts: 22
Rep Power: 0 MR.T is on a distinguished road
XML minidom... help

I have been programming in python off and on and I am trying to really sit down and get more proficient in it this summer.

Right now I am trying to make a basic program for reading, modifying and writing data with an XML file. I am using minidom and I and here is the problem I am running into. Say I have a game inventory or something like this:

<Inv>
	<Sword>
		<Name>Broad Sword</Name>
	</Sword>
	<Shield>
		<Name>Big Shield</Name>
	</Shield>
</Inv>

I want to return the Name section of Shield. If I use a function like "getElementsByTagName" then it will return a list containing the contents of all Name sections. How do I explicitly tell minidom to get an element in... say this order Inv>Shield>Name? I tried setting it up so it loaded the elements in that order i.e I loaded Inv into a variable then I loaded Shield and finally Name. That works fine if the document is small, but obviously that's inefficient, and I cant save the file if I choose to modify an element.

I'm sure there is something simple that I am forgetting or that I missed(there always seems to be in python). Can someone please steer me in the right direction.
__________________
"Gee, Brain, what do you want to do tonight?" "The same thing we do every night, Pinky: Try to take over the world!"
MR.T is offline   Reply With Quote
Old Jun 9th, 2007, 9:03 AM   #2
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
python Syntax (Toggle Plain Text)
  1. import xml.dom.minidom
  2. xml = xml.dom.minidom.parseString("""<Inv>
  3. ... <Sword>
  4. ... <Name>Broad Sword</Name>
  5. ... </Sword>
  6. ... <Shield>
  7. ... <Name>Big Shield</Name>
  8. ... </Shield>
  9. ... </Inv>""")
  10.  
  11. # Assume only one inventory
  12. inv = xml.getElementsByTagName("Inv")[0]
  13.  
  14. # Get all shields in inventory
  15. shields = inv.getElementsByTagName("Shield")
  16.  
  17. # For each shield, print out its name
  18. for shield in shields:
  19. # Assume shield has only one name
  20. name = shield.getElementsByTagName("Name")[0]
  21.  
  22. # Assume name tag just has text in it
  23. print name.firstChild.wholeText
Generally speaking though, there's easier ways of storing human-readable game data in Python, unless you happen to want your data to be cross-platform.
Arevos is offline   Reply With Quote
Old Jun 9th, 2007, 1:19 PM   #3
MR.T
Newbie
 
MR.T's Avatar
 
Join Date: Feb 2006
Location: USA,Michigan
Posts: 22
Rep Power: 0 MR.T is on a distinguished road
Well what you posted is essentially what I did do read data from an XML file. However my problem really is about modifying the file. Say I want to change the "Broad Sword" to "Short Sword" or add another element to my XML file. I could do it that way, but wouldn't the changes just take place to the code that was in the variable? How do I modify and save the document.
__________________
"Gee, Brain, what do you want to do tonight?" "The same thing we do every night, Pinky: Try to take over the world!"
MR.T is offline   Reply With Quote
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: 4 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
Old Jun 9th, 2007, 11:16 PM   #5
MR.T
Newbie
 
MR.T's Avatar
 
Join Date: Feb 2006
Location: USA,Michigan
Posts: 22
Rep Power: 0 MR.T is on a distinguished road
Ok I see, thank you very much for the informative post
__________________
"Gee, Brain, what do you want to do tonight?" "The same thing we do every night, Pinky: Try to take over the world!"
MR.T is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Adding nodes with minidom MegaArcon Python 4 Feb 21st, 2006 12:37 PM
XML - changing textnodes with minidom tantric Python 3 Apr 26th, 2005 6:44 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 4:54 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC