[Edu-sig] Rich Data Structures (cont.)
Kirby Urner
urnerk at qwest.net
Thu Nov 3 01:12:09 CET 2005
> A useful curriculum segment would be to take the above xml and run it
> through a parser to create a bunch of city objects with lat and long
> attributes, i.e. XML used to instantiate objects. That'd be a good "cave
> painting" (= simplification, many essential aspects conveyed) of many real
> world applications (e.g. XAML).
>
> Kirby
Just to round this out:
My cities dict --> XML function made the mistake of not creating a 'root'
tag, i.e. the <city></city> elements floated outside any container. The SAX
parser (SAX = Simple API for XML) didn't like that.
So...
A fixed function:
# whatever path
thepath = "c:/documents and settings/kirby/My Documents/"
def makexml(thefile):
"""
dict --> XML file
The dict in question is on file here:
http://mail.python.org/pipermail/edu-sig/2005-October/005500.html
"""
f = open(thepath + thefile, 'w')
f.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
f.write('<cities>\n')
for city in cities: # cities is a global in this context
loc = tuple([s.strip() for s in city.split(',')])
if len(loc)==3:
f.write('<city name="%s" state="%s" country="%s">\n' % loc)
else:
f.write('<city name="%s" state="%s">\n' % loc)
f.write('\t<lat deg="%s" min="%s" dir="%s" />\n' % cities[city][0])
f.write('\t<long deg="%s" min="%s" dir="%s" />\n' % cities[city][1])
f.write('</city>\n')
f.write('</cities>\n')
f.close()
And here's another to read back the XML so generated, and recreate the dict.
Not very elaborate or general, but enough to give some ideas I think.
from xml.sax import make_parser
from xml.sax.handler import ContentHandler
class CityHandler(ContentHandler):
"""
Run through an XML file in a specific format:
<cities>
<city name="Toronto" state="Ont." country="Can.">
<lat deg="43" min="40" dir="W" />
<long deg="79" min="24" dir="N" />
</city>
<city name="Nashville" state="Tenn.">
<lat deg="36" min="10" dir="W" />
<long deg="86" min="47" dir="N" />
</city>
</cities>
Create a dictionary like the one used to create
the XML in the first place.
"""
def __init__(self):
self.thedict = {}
self.key = ''
self.latlong = []
def startElement(self, name, attrs):
if name=='city':
key = "%s, %s" % (str(attrs.get('name')),
str(attrs.get('state')))
country = str(attrs.get('country','')) # optional attribute
if country<>'':
key = key + ", " + country
self.key = key
if name in ['lat','long']:
# build a list of two tuples of form (deg, min, dir)
# using str because we don't want unicode
self.latlong.append(
(int(attrs.get('deg')),
int(attrs.get('min')),
str(attrs.get('dir'))))
if name=='long':
# time to create a new dict entry and start new city
self.thedict[self.key]=self.latlong
self.latlong=[]
self.key=''
def makecities(thefile):
"""
Take the xml file created above and reconstitute the same dictionary.
"""
parser = make_parser()
thehandler = CityHandler()
parser.setContentHandler(thehandler)
parser.parse(thepath + thefile)
print thehandler.thedict
OK, I think that's enough for now. XML freaks could go a *lot* further. My
goal is to keep it basic basic.
Kirby
More information about the Edu-sig
mailing list