__all__ = ('xml_from_string', 'xml_from_file' ) import libxml2 class _ErrorHandler ( object ): def __init__ ( self ): self._msgs = [] self._do_print = False return def __call__ ( self, first, second ): if self._do_print: print second else: self._msgs.append(second) return def reset ( self ): self._msgs = [] return def get_message ( self ): return ''.join(self._msgs) def set_print ( self, flag ): self._do_print = bool(flag) return def print_message ( self ): print self.get_messages() return # ### _error_handler = _ErrorHandler() libxml2.registerErrorHandler(_error_handler, None) ### class DavXmlParseError ( Exception ): pass # ### class _XpathContext ( object ): def __init__ ( self, doc ): self.doc = doc self.nsmap = { 'D':'DAV:', 'd':'DAV:' } self.ctx = None return def init ( self ): if self.ctx is not None: return self.ctx = self.doc.xpathNewContext() for k, v in self.nsmap.items(): self.add_namespace(k, v) return def free ( self ): self.ctx.xpathFreeContext() return def add_namespace ( self, prefix, uri ): if self.ctx is None: self.init() self.nsmap[prefix] = uri self.ctx.xpathRegisterNs(prefix, uri) return def evaluate ( self, expr, root=None ): if self.ctx is None: self.init() c = self.ctx if root is None: root = self.doc c.setContextNode(root) res = c.xpathEval(expr) return res # ### class _DavXmlDoc: def __init__ ( self ): self.doc = None self.ctx = None return def from_string ( self, data ): global _error_handler _error_handler.reset() try: doc = libxml2.parseDoc(data) except libxml2.parserError, ex: m = _error_handler.get_message() raise DavXmlParseError, m self.doc = doc self.ctx = _XpathContext(self.doc) return def from_file ( self, fname ): global _error_handler _error_handler.reset() try: doc = libxml2.parseFile(fname) except libxml2.parserError, ex: m = _error_handler.get_message() raise DavXmlParseError, m self.doc = doc self.ctx = _XpathContext(self.doc) return def free ( self ): self.ctx.free() self.ctx = None self.doc.freeDoc() self.doc = None return def xpathEval ( self, expr, root=None ): if root is not None: expr = root.nodePath() + '/' + expr return self.ctx.evaluate(expr) def xpathWalk ( self, expr, fnc ): for n in self.ctx.evaluate(expr): if fnc(n): break return def get_response_nodes ( self ): res = self.ctx.evaluate('//D:response') return res # [ r.nodePath() for r in res ] def get_property_nodes ( self, root ): p = root.nodePath() + '/D:propstat/D:prop/*' return self.ctx.evaluate(p) # ### def xml_from_string( data ): d = _DavXmlDoc() d.from_string(data) return d # def xml_from_file ( f_in ): d = _DavXmlDoc() d.from_file(f_in) return d #