[XML-SIG] "simple" config file parser problems
J B Bell
cipher@redback.com
Tue, 29 May 2001 10:31:29 -0700
I'm having the very devil of a time trying to do something that I
assume would be simple (if I knew what I was doing) with xml.sax under
Python 2.0 & 2.1.
I'd go into the structure I'm looking to get from the XML, but at this
point, the event-handling methods I have don't come into play before
something deep inside xml.expat explodes. Likely the object I'm using
lacks a needed trait (it appears to be something to do with name,
though that seems to be there), but I'm not sure what.
Without further ado, too much code, followed by a stack trace. Any
help at all is greatly appreciated. If this isn't the appropriate
list, please accept my copious apologies, and if you are kindly
disposed, a pointer to the right place to get assistance would be a
bonus.
--JB
# Note, I have tried with both saxlib.HandlerBase and the presumably
# more generic ContentHandler. Both give the exact same error.
from xml.sax import make_parser
from xml.sax import saxlib
from xml.sax.handler import feature_namespaces
from xml.sax import ContentHandler
class Config:
"""A base class for all types of configuration information, whether to be
found in plain files, xml, or databases. Subclass as appropriate."""
def parseConfig(self, args):
"""Override this in your subclassed Config"""
pass
def __init__(self, *args):
newConfig = self.parseConfig(args)
return newConfig
#class RsyncConfigHandler(ContentHandler):
class RsyncConfigHandler(saxlib.HandlerBase):
"""Read in & return a config file for rsync jobs"""
# Errors should be signaled, so we'll output a message and raise
# the exception to stop processing
def fatalError(self, exception):
sys.stderr.write('ERROR: '+ str(exception)+'\n')
sys.exit(1)
error = fatalError
warning = fatalError
def startDocument(self):
self.jobList = []
def startElement(self, name, attrs):
methodName = "start" + str(name).capitalize()
try:
method = getattr(self, methodName)
except:
raise "Unknown element name '<%s>'" % name
self.attrs = attrs
if DEBUG: print "Invoking %s with attrs %s" % (methodName, str(attrs))
apply(method, attrs)
def endElement(self, name):
methodName = "start" + str(name).capitalize()
try:
method = getattr(self, methodName)
except:
raise "Unknown element name '</%s>'" % name
if DEBUG: print "Invoking %s with attrs %s" % (methodName, str(attrs))
apply(method, attrs)
def startConfig(self, attrs):
"""<config> just starts the whole shebang, no need to do anything."""
pass
def endConfig(self):
pass
def startQueue(self, attrs):
pass
def endQueue(self):
pass
def startJob(self, attrs):
pass
def endJob(self):
pass
class RsyncConfig(Config):
"""Return an rsync configuration object"""
def parseConfig(self, args):
parser = make_parser()
parser.setFeature(feature_namespaces, 0)
dh = RsyncConfigHandler() # Might want arguments here one day
parser.setContentHandler(dh)
configFile = "/home/cipher/cvs/itdoc/servers/rsync_config.xml"
parser.parse(configFile)
[And now the stack trace:]
Python 2.0 (#1, Nov 3 2000, 12:11:00)
[GCC egcs-2.91.66 19990314 (egcs-1.1.2 release)] on netbsd1
Type "copyright", "credits" or "license" for more information.
>>> from rsynct import RsyncConfig
>>> foo = RsyncConfig()
Invoking startConfig with attrs <xml.sax.xmlreader.AttributesImpl
instance at 0x8309bcc>
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "rsynct.py", line 65, in __init__
newConfig = self.parseConfig(args)
File "rsynct.py", line 129, in parseConfig
parser.parse(configFile)
File
"/usr/pkg/lib/python2.0/site-packages/_xmlplus/sax/expatreader.py",
line 43, in parse
xmlreader.IncrementalParser.parse(self, source)
File
"/usr/pkg/lib/python2.0/site-packages/_xmlplus/sax/xmlreader.py", line
121, in parse
self.feed(buffer)
File
"/usr/pkg/lib/python2.0/site-packages/_xmlplus/sax/expatreader.py",
line 87, in feed
self._parser.Parse(data, isFinal)
File
"/usr/pkg/lib/python2.0/site-packages/_xmlplus/sax/expatreader.py",
line 155, in start_element
self._cont_handler.startElement(name, AttributesImpl(attrs))
File "rsynct.py", line 90, in startElement
apply(method, attrs)
File
"/usr/pkg/lib/python2.0/site-packages/_xmlplus/sax/xmlreader.py", line
314, in __getitem__
return self._attrs[name]
KeyError: 0