[xml-bindings]Python bindings suggestions
- From: Gary Benson <gary inauspicious org>
- To: xml-bindings gnome org
- Subject: [xml-bindings]Python bindings suggestions
- Date: Mon, 4 Mar 2002 22:05:03 +0000 (GMT)
Hi all,
Okay, over the past few days I've been using the Python bindings a lot,
and have tripped a few things (probably because I've done very little
libxml programming in C so I don't have any preconceived notions of how
the library works). So I have a couple of suggestions (which can hopefully
be dealt with in the automatic code generator) and a couple of questions:
One thing I'd like to get rid of is all the 'if ret == None: return None's
that signify that something failed in libxml2.py. The Python way of doing
this is very much "if something fails, throw an exception". I tend to use
something like this for my stuff:
class error(exceptions.Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
This would probably be more easily done in the Python part:
ret = _libxml.xmlNewTextChild(self._o, ns__o, name, content)
if ret == None: raise error("xmlNewTextChild() failed")
That way you get something like "libxml2.error: xmlNewTextChild() failed"
in the backtrace, and you can "except libxml2.error" to catch problems if
you want. Hopefully this won't be too hard to implement since I understand
that libxml2.py is automatically generated anyway.
My second suggestion is this: in quite a lot of Python modules where is
something that requires a callback there will be an example one filled
with empty functions. For the SAX parser, for example, something like
(only a couple of methods shown):
class SAXCallback:
"""Base class for SAX handlers"""
def startElement(self, tag, attrs):
"""Called at the start of every element.
TAG is the name of the element
ATTRS is a dictionary of the element's attributes
"""
pass
def endElement(self, tag):
"""Called at the end of every element
TAG is the name of the element
"""
pass
# ... other methods ...
def warning(self, msg):
raise error(msg)
def error(self, msg):
raise error(msg)
def fatalError(self, msg):
raise error(msg)
That way, all the error handling stuff is there already (unless they
override it with something less severe) and they have a template that
basically documents itself.
Finally, I had a couple of questions:
1. The only SAX parser creator seems to be a memory parser -- is there a
way of creating one that will parse a file instead? I'm currently
using something like:
def parseFile(path, handler):
ctxt = None
file = open(path, "r")
while 1:
chunk = file.read(1024)
if len(chunk) == 0:
break
if not ctxt:
ctxt = libxml2.createPushParser(handler, chunk, len(chunk), path)
else:
ctxt.parseChunk(chunk, len(chunk), len(chunk)!=1024)
It's not a problem, but it seems like something I should be able to do
with the library.
2. I tried using the following bit of XPath but it didn't return any nodes
(it should have returned one). Have I done something stupid, or is it
a bug?
film = "022"
doc = libxml2.parseFile(path)
ctxt = doc.xpathNewContext()
nodes = ctxt.xpathEval("/photodb/film[ num=%s]" % film)
3. How do you evaluate an XPath expression with a relative path? For
instance, if the above example had worked and nodes[0] was an xmlNode,
how would I select into it? I'd _expect_ to do something like:
film_node = nodes[0]
photo = "12"
ctxt2 = film_node.xpathNewContext()
nodes2 = ctxt2.xpathEval(photo[ num=%s]" % photo)
But of course that doesn't work ;-)
Thanks in advance,
Gary
[ gary inauspicious org ][ GnuPG 85A8F78B ][ http://inauspicious.org/ ]
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]