789 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			789 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			Python
		
	
	
	
import libxml2mod
 | 
						|
import types
 | 
						|
import sys
 | 
						|
 | 
						|
# The root of all libxml2 errors.
 | 
						|
class libxmlError(Exception): pass
 | 
						|
 | 
						|
# Type of the wrapper class for the C objects wrappers
 | 
						|
def checkWrapper(obj):
 | 
						|
    try:
 | 
						|
        n = type(_obj).__name__
 | 
						|
        if n != 'PyCObject' and n != 'PyCapsule':
 | 
						|
            return 1
 | 
						|
    except:
 | 
						|
        return 0
 | 
						|
    return 0
 | 
						|
 | 
						|
#
 | 
						|
# id() is sometimes negative ...
 | 
						|
#
 | 
						|
def pos_id(o):
 | 
						|
    i = id(o)
 | 
						|
    if (i < 0):
 | 
						|
        return (sys.maxsize - i)
 | 
						|
    return i
 | 
						|
 | 
						|
#
 | 
						|
# Errors raised by the wrappers when some tree handling failed.
 | 
						|
#
 | 
						|
class treeError(libxmlError):
 | 
						|
    def __init__(self, msg):
 | 
						|
        self.msg = msg
 | 
						|
    def __str__(self):
 | 
						|
        return self.msg
 | 
						|
 | 
						|
class parserError(libxmlError):
 | 
						|
    def __init__(self, msg):
 | 
						|
        self.msg = msg
 | 
						|
    def __str__(self):
 | 
						|
        return self.msg
 | 
						|
 | 
						|
class uriError(libxmlError):
 | 
						|
    def __init__(self, msg):
 | 
						|
        self.msg = msg
 | 
						|
    def __str__(self):
 | 
						|
        return self.msg
 | 
						|
 | 
						|
class xpathError(libxmlError):
 | 
						|
    def __init__(self, msg):
 | 
						|
        self.msg = msg
 | 
						|
    def __str__(self):
 | 
						|
        return self.msg
 | 
						|
 | 
						|
class ioWrapper:
 | 
						|
    def __init__(self, _obj):
 | 
						|
        self.__io = _obj
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def io_close(self):
 | 
						|
        if self.__io == None:
 | 
						|
            return(-1)
 | 
						|
        self.__io.close()
 | 
						|
        self.__io = None
 | 
						|
        return(0)
 | 
						|
 | 
						|
    def io_flush(self):
 | 
						|
        if self.__io == None:
 | 
						|
            return(-1)
 | 
						|
        self.__io.flush()
 | 
						|
        return(0)
 | 
						|
 | 
						|
    def io_read(self, len = -1):
 | 
						|
        if self.__io == None:
 | 
						|
            return(-1)
 | 
						|
        try:
 | 
						|
            if len < 0:
 | 
						|
                ret = self.__io.read()
 | 
						|
            else:
 | 
						|
                ret = self.__io.read(len)
 | 
						|
        except Exception:
 | 
						|
            import sys
 | 
						|
            e = sys.exc_info()[1]
 | 
						|
            print("failed to read from Python:", type(e))
 | 
						|
            print("on IO:", self.__io)
 | 
						|
            self.__io == None
 | 
						|
            return(-1)
 | 
						|
 | 
						|
        return(ret)
 | 
						|
 | 
						|
    def io_write(self, str, len = -1):
 | 
						|
        if self.__io == None:
 | 
						|
            return(-1)
 | 
						|
        if len < 0:
 | 
						|
            return(self.__io.write(str))
 | 
						|
        return(self.__io.write(str, len))
 | 
						|
 | 
						|
class ioReadWrapper(ioWrapper):
 | 
						|
    def __init__(self, _obj, enc = ""):
 | 
						|
        ioWrapper.__init__(self, _obj)
 | 
						|
        self._o = libxml2mod.xmlCreateInputBuffer(self, enc)
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
        print("__del__")
 | 
						|
        self.io_close()
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlFreeParserInputBuffer(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        self.io_close()
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlFreeParserInputBuffer(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
class ioWriteWrapper(ioWrapper):
 | 
						|
    def __init__(self, _obj, enc = ""):
 | 
						|
#        print "ioWriteWrapper.__init__", _obj
 | 
						|
        if type(_obj) == type(''):
 | 
						|
            print("write io from a string")
 | 
						|
            self.o = None
 | 
						|
        elif type(_obj).__name__ == 'PyCapsule':
 | 
						|
            file = libxml2mod.outputBufferGetPythonFile(_obj)
 | 
						|
            if file != None:
 | 
						|
                ioWrapper.__init__(self, file)
 | 
						|
            else:
 | 
						|
                ioWrapper.__init__(self, _obj)
 | 
						|
            self._o = _obj
 | 
						|
#        elif type(_obj) == types.InstanceType:
 | 
						|
#            print(("write io from instance of %s" % (_obj.__class__)))
 | 
						|
#            ioWrapper.__init__(self, _obj)
 | 
						|
#            self._o = libxml2mod.xmlCreateOutputBuffer(self, enc)
 | 
						|
        else:
 | 
						|
            file = libxml2mod.outputBufferGetPythonFile(_obj)
 | 
						|
            if file != None:
 | 
						|
                ioWrapper.__init__(self, file)
 | 
						|
            else:
 | 
						|
                ioWrapper.__init__(self, _obj)
 | 
						|
            self._o = _obj
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
#        print "__del__"
 | 
						|
        self.io_close()
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlOutputBufferClose(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def flush(self):
 | 
						|
        self.io_flush()
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlOutputBufferClose(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def close(self):
 | 
						|
        self.io_flush()
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlOutputBufferClose(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
#
 | 
						|
# Example of a class to handle SAX events
 | 
						|
#
 | 
						|
class SAXCallback:
 | 
						|
    """Base class for SAX handlers"""
 | 
						|
    def startDocument(self):
 | 
						|
        """called at the start of the document"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def endDocument(self):
 | 
						|
        """called at the end of the document"""
 | 
						|
        pass
 | 
						|
 | 
						|
    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 start of every element, tag is the name of
 | 
						|
           the element"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def characters(self, data):
 | 
						|
        """called when character data have been read, data is the string
 | 
						|
           containing the data, multiple consecutive characters() callback
 | 
						|
           are possible."""
 | 
						|
        pass
 | 
						|
 | 
						|
    def cdataBlock(self, data):
 | 
						|
        """called when CDATA section have been read, data is the string
 | 
						|
           containing the data, multiple consecutive cdataBlock() callback
 | 
						|
           are possible."""
 | 
						|
        pass
 | 
						|
 | 
						|
    def reference(self, name):
 | 
						|
        """called when an entity reference has been found"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def ignorableWhitespace(self, data):
 | 
						|
        """called when potentially ignorable white spaces have been found"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def processingInstruction(self, target, data):
 | 
						|
        """called when a PI has been found, target contains the PI name and
 | 
						|
           data is the associated data in the PI"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def comment(self, content):
 | 
						|
        """called when a comment has been found, content contains the comment"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def externalSubset(self, name, externalID, systemID):
 | 
						|
        """called when a DOCTYPE declaration has been found, name is the
 | 
						|
           DTD name and externalID, systemID are the DTD public and system
 | 
						|
           identifier for that DTd if available"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def internalSubset(self, name, externalID, systemID):
 | 
						|
        """called when a DOCTYPE declaration has been found, name is the
 | 
						|
           DTD name and externalID, systemID are the DTD public and system
 | 
						|
           identifier for that DTD if available"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def entityDecl(self, name, type, externalID, systemID, content):
 | 
						|
        """called when an ENTITY declaration has been found, name is the
 | 
						|
           entity name and externalID, systemID are the entity public and
 | 
						|
           system identifier for that entity if available, type indicates
 | 
						|
           the entity type, and content reports it's string content"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def notationDecl(self, name, externalID, systemID):
 | 
						|
        """called when an NOTATION declaration has been found, name is the
 | 
						|
           notation name and externalID, systemID are the notation public and
 | 
						|
           system identifier for that notation if available"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def attributeDecl(self, elem, name, type, defi, defaultValue, nameList):
 | 
						|
        """called when an ATTRIBUTE definition has been found"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def elementDecl(self, name, type, content):
 | 
						|
        """called when an ELEMENT definition has been found"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def entityDecl(self, name, publicId, systemID, notationName):
 | 
						|
        """called when an unparsed ENTITY declaration has been found,
 | 
						|
           name is the entity name and publicId,, systemID are the entity
 | 
						|
           public and system identifier for that entity if available,
 | 
						|
           and notationName indicate the associated NOTATION"""
 | 
						|
        pass
 | 
						|
 | 
						|
    def warning(self, msg):
 | 
						|
        #print msg
 | 
						|
        pass
 | 
						|
 | 
						|
    def error(self, msg):
 | 
						|
        raise parserError(msg)
 | 
						|
 | 
						|
    def fatalError(self, msg):
 | 
						|
        raise parserError(msg)
 | 
						|
 | 
						|
#
 | 
						|
# This class is the ancestor of all the Node classes. It provides
 | 
						|
# the basic functionalities shared by all nodes (and handle
 | 
						|
# gracefylly the exception), like name, navigation in the tree,
 | 
						|
# doc reference, content access and serializing to a string or URI
 | 
						|
#
 | 
						|
class xmlCore:
 | 
						|
    def __init__(self, _obj=None):
 | 
						|
        if _obj != None: 
 | 
						|
            self._o = _obj;
 | 
						|
            return
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def __eq__(self, other):
 | 
						|
        if other == None:
 | 
						|
            return False
 | 
						|
        ret = libxml2mod.compareNodesEqual(self._o, other._o)
 | 
						|
        if ret == None:
 | 
						|
            return False
 | 
						|
        return ret == True
 | 
						|
    def __ne__(self, other):
 | 
						|
        if other == None:
 | 
						|
            return True
 | 
						|
        ret = libxml2mod.compareNodesEqual(self._o, other._o)
 | 
						|
        return not ret
 | 
						|
    def __hash__(self):
 | 
						|
        ret = libxml2mod.nodeHash(self._o)
 | 
						|
        return ret
 | 
						|
 | 
						|
    def __str__(self):
 | 
						|
        return self.serialize()
 | 
						|
    def get_parent(self):
 | 
						|
        ret = libxml2mod.parent(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return nodeWrap(ret)
 | 
						|
    def get_children(self):
 | 
						|
        ret = libxml2mod.children(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return nodeWrap(ret)
 | 
						|
    def get_last(self):
 | 
						|
        ret = libxml2mod.last(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return nodeWrap(ret)
 | 
						|
    def get_next(self):
 | 
						|
        ret = libxml2mod.next(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return nodeWrap(ret)
 | 
						|
    def get_properties(self):
 | 
						|
        ret = libxml2mod.properties(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return xmlAttr(_obj=ret)
 | 
						|
    def get_prev(self):
 | 
						|
        ret = libxml2mod.prev(self._o)
 | 
						|
        if ret == None:
 | 
						|
            return None
 | 
						|
        return nodeWrap(ret)
 | 
						|
    def get_content(self):
 | 
						|
        return libxml2mod.xmlNodeGetContent(self._o)
 | 
						|
    getContent = get_content  # why is this duplicate naming needed ?
 | 
						|
    def get_name(self):
 | 
						|
        return libxml2mod.name(self._o)
 | 
						|
    def get_type(self):
 | 
						|
        return libxml2mod.type(self._o)
 | 
						|
    def get_doc(self):
 | 
						|
        ret = libxml2mod.doc(self._o)
 | 
						|
        if ret == None:
 | 
						|
            if self.type in ["document_xml", "document_html"]:
 | 
						|
                return xmlDoc(_obj=self._o)
 | 
						|
            else:
 | 
						|
                return None
 | 
						|
        return xmlDoc(_obj=ret)
 | 
						|
    #
 | 
						|
    # Those are common attributes to nearly all type of nodes
 | 
						|
    # defined as python2 properties
 | 
						|
    # 
 | 
						|
    import sys
 | 
						|
    if float(sys.version[0:3]) < 2.2:
 | 
						|
        def __getattr__(self, attr):
 | 
						|
            if attr == "parent":
 | 
						|
                ret = libxml2mod.parent(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return nodeWrap(ret)
 | 
						|
            elif attr == "properties":
 | 
						|
                ret = libxml2mod.properties(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return xmlAttr(_obj=ret)
 | 
						|
            elif attr == "children":
 | 
						|
                ret = libxml2mod.children(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return nodeWrap(ret)
 | 
						|
            elif attr == "last":
 | 
						|
                ret = libxml2mod.last(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return nodeWrap(ret)
 | 
						|
            elif attr == "next":
 | 
						|
                ret = libxml2mod.next(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return nodeWrap(ret)
 | 
						|
            elif attr == "prev":
 | 
						|
                ret = libxml2mod.prev(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    return None
 | 
						|
                return nodeWrap(ret)
 | 
						|
            elif attr == "content":
 | 
						|
                return libxml2mod.xmlNodeGetContent(self._o)
 | 
						|
            elif attr == "name":
 | 
						|
                return libxml2mod.name(self._o)
 | 
						|
            elif attr == "type":
 | 
						|
                return libxml2mod.type(self._o)
 | 
						|
            elif attr == "doc":
 | 
						|
                ret = libxml2mod.doc(self._o)
 | 
						|
                if ret == None:
 | 
						|
                    if self.type == "document_xml" or self.type == "document_html":
 | 
						|
                        return xmlDoc(_obj=self._o)
 | 
						|
                    else:
 | 
						|
                        return None
 | 
						|
                return xmlDoc(_obj=ret)
 | 
						|
            raise AttributeError(attr)
 | 
						|
    else:
 | 
						|
        parent = property(get_parent, None, None, "Parent node")
 | 
						|
        children = property(get_children, None, None, "First child node")
 | 
						|
        last = property(get_last, None, None, "Last sibling node")
 | 
						|
        next = property(get_next, None, None, "Next sibling node")
 | 
						|
        prev = property(get_prev, None, None, "Previous sibling node")
 | 
						|
        properties = property(get_properties, None, None, "List of properties")
 | 
						|
        content = property(get_content, None, None, "Content of this node")
 | 
						|
        name = property(get_name, None, None, "Node name")
 | 
						|
        type = property(get_type, None, None, "Node type")
 | 
						|
        doc = property(get_doc, None, None, "The document this node belongs to")
 | 
						|
 | 
						|
    #
 | 
						|
    # Serialization routines, the optional arguments have the following
 | 
						|
    # meaning:
 | 
						|
    #     encoding: string to ask saving in a specific encoding
 | 
						|
    #     indent: if 1 the serializer is asked to indent the output
 | 
						|
    #
 | 
						|
    def serialize(self, encoding = None, format = 0):
 | 
						|
        return libxml2mod.serializeNode(self._o, encoding, format)
 | 
						|
    def saveTo(self, file, encoding = None, format = 0):
 | 
						|
        return libxml2mod.saveNodeTo(self._o, file, encoding, format)
 | 
						|
            
 | 
						|
    #
 | 
						|
    # Canonicalization routines:
 | 
						|
    #
 | 
						|
    #   nodes: the node set (tuple or list) to be included in the
 | 
						|
    #     canonized image or None if all document nodes should be
 | 
						|
    #     included.
 | 
						|
    #   exclusive: the exclusive flag (0 - non-exclusive
 | 
						|
    #     canonicalization; otherwise - exclusive canonicalization)
 | 
						|
    #   prefixes: the list of inclusive namespace prefixes (strings),
 | 
						|
    #     or None if there is no inclusive namespaces (only for
 | 
						|
    #     exclusive canonicalization, ignored otherwise)
 | 
						|
    #   with_comments: include comments in the result (!=0) or not
 | 
						|
    #     (==0)
 | 
						|
    def c14nMemory(self,
 | 
						|
                   nodes=None,
 | 
						|
                   exclusive=0,
 | 
						|
                   prefixes=None,
 | 
						|
                   with_comments=0):
 | 
						|
        if nodes:
 | 
						|
            nodes = [n._o for n in nodes]
 | 
						|
        return libxml2mod.xmlC14NDocDumpMemory(
 | 
						|
            self.get_doc()._o,
 | 
						|
            nodes,
 | 
						|
            exclusive != 0,
 | 
						|
            prefixes,
 | 
						|
            with_comments != 0)
 | 
						|
    def c14nSaveTo(self,
 | 
						|
                   file,
 | 
						|
                   nodes=None,
 | 
						|
                   exclusive=0,
 | 
						|
                   prefixes=None,
 | 
						|
                   with_comments=0):
 | 
						|
        if nodes:
 | 
						|
            nodes = [n._o for n in nodes]
 | 
						|
        return libxml2mod.xmlC14NDocSaveTo(
 | 
						|
            self.get_doc()._o,
 | 
						|
            nodes,
 | 
						|
            exclusive != 0,
 | 
						|
            prefixes,
 | 
						|
            with_comments != 0,
 | 
						|
            file)
 | 
						|
 | 
						|
    #
 | 
						|
    # Selecting nodes using XPath, a bit slow because the context
 | 
						|
    # is allocated/freed every time but convenient.
 | 
						|
    #
 | 
						|
    def xpathEval(self, expr):
 | 
						|
        doc = self.doc
 | 
						|
        if doc == None:
 | 
						|
            return None
 | 
						|
        ctxt = doc.xpathNewContext()
 | 
						|
        ctxt.setContextNode(self)
 | 
						|
        res = ctxt.xpathEval(expr)
 | 
						|
        ctxt.xpathFreeContext()
 | 
						|
        return res
 | 
						|
 | 
						|
#    #
 | 
						|
#    # Selecting nodes using XPath, faster because the context
 | 
						|
#    # is allocated just once per xmlDoc.
 | 
						|
#    #
 | 
						|
#    # Removed: DV memleaks c.f. #126735
 | 
						|
#    #
 | 
						|
#    def xpathEval2(self, expr):
 | 
						|
#        doc = self.doc
 | 
						|
#        if doc == None:
 | 
						|
#            return None
 | 
						|
#        try:
 | 
						|
#            doc._ctxt.setContextNode(self)
 | 
						|
#        except:
 | 
						|
#            doc._ctxt = doc.xpathNewContext()
 | 
						|
#            doc._ctxt.setContextNode(self)
 | 
						|
#        res = doc._ctxt.xpathEval(expr)
 | 
						|
#        return res
 | 
						|
    def xpathEval2(self, expr):
 | 
						|
        return self.xpathEval(expr)
 | 
						|
 | 
						|
    # Remove namespaces
 | 
						|
    def removeNsDef(self, href):
 | 
						|
        """
 | 
						|
        Remove a namespace definition from a node.  If href is None,
 | 
						|
        remove all of the ns definitions on that node.  The removed
 | 
						|
        namespaces are returned as a linked list.
 | 
						|
 | 
						|
        Note: If any child nodes referred to the removed namespaces,
 | 
						|
        they will be left with dangling links.  You should call
 | 
						|
        renconciliateNs() to fix those pointers.
 | 
						|
 | 
						|
        Note: This method does not free memory taken by the ns
 | 
						|
        definitions.  You will need to free it manually with the
 | 
						|
        freeNsList() method on the returns xmlNs object.
 | 
						|
        """
 | 
						|
 | 
						|
        ret = libxml2mod.xmlNodeRemoveNsDef(self._o, href)
 | 
						|
        if ret is None:return None
 | 
						|
        __tmp = xmlNs(_obj=ret)
 | 
						|
        return __tmp
 | 
						|
 | 
						|
    # support for python2 iterators
 | 
						|
    def walk_depth_first(self):
 | 
						|
        return xmlCoreDepthFirstItertor(self)
 | 
						|
    def walk_breadth_first(self):
 | 
						|
        return xmlCoreBreadthFirstItertor(self)
 | 
						|
    __iter__ = walk_depth_first
 | 
						|
 | 
						|
    def free(self):
 | 
						|
        try:
 | 
						|
            self.doc._ctxt.xpathFreeContext()
 | 
						|
        except:
 | 
						|
            pass
 | 
						|
        libxml2mod.xmlFreeDoc(self._o)
 | 
						|
 | 
						|
 | 
						|
#
 | 
						|
# implements the depth-first iterator for libxml2 DOM tree
 | 
						|
#
 | 
						|
class xmlCoreDepthFirstItertor:
 | 
						|
    def __init__(self, node):
 | 
						|
        self.node = node
 | 
						|
        self.parents = []
 | 
						|
    def __iter__(self):
 | 
						|
        return self
 | 
						|
    def __next__(self):
 | 
						|
        while 1:
 | 
						|
            if self.node:
 | 
						|
                ret = self.node
 | 
						|
                self.parents.append(self.node)
 | 
						|
                self.node = self.node.children
 | 
						|
                return ret
 | 
						|
            try:
 | 
						|
                parent = self.parents.pop()
 | 
						|
            except IndexError:
 | 
						|
                raise StopIteration
 | 
						|
            self.node = parent.next
 | 
						|
    next = __next__
 | 
						|
 | 
						|
#
 | 
						|
# implements the breadth-first iterator for libxml2 DOM tree
 | 
						|
#
 | 
						|
class xmlCoreBreadthFirstItertor:
 | 
						|
    def __init__(self, node):
 | 
						|
        self.node = node
 | 
						|
        self.parents = []
 | 
						|
    def __iter__(self):
 | 
						|
        return self
 | 
						|
    def __next__(self):
 | 
						|
        while 1:
 | 
						|
            if self.node:
 | 
						|
                ret = self.node
 | 
						|
                self.parents.append(self.node)
 | 
						|
                self.node = self.node.next
 | 
						|
                return ret
 | 
						|
            try:
 | 
						|
                parent = self.parents.pop()
 | 
						|
            except IndexError:
 | 
						|
                raise StopIteration
 | 
						|
            self.node = parent.children
 | 
						|
    next = __next__
 | 
						|
 | 
						|
#
 | 
						|
# converters to present a nicer view of the XPath returns
 | 
						|
#
 | 
						|
def nodeWrap(o):
 | 
						|
    # TODO try to cast to the most appropriate node class
 | 
						|
    name = libxml2mod.type(o)
 | 
						|
    if name == "element" or name == "text":
 | 
						|
        return xmlNode(_obj=o)
 | 
						|
    if name == "attribute":
 | 
						|
        return xmlAttr(_obj=o)
 | 
						|
    if name[0:8] == "document":
 | 
						|
        return xmlDoc(_obj=o)
 | 
						|
    if name == "namespace":
 | 
						|
        return xmlNs(_obj=o)
 | 
						|
    if name == "elem_decl":
 | 
						|
        return xmlElement(_obj=o)
 | 
						|
    if name == "attribute_decl":
 | 
						|
        return xmlAttribute(_obj=o)
 | 
						|
    if name == "entity_decl":
 | 
						|
        return xmlEntity(_obj=o)
 | 
						|
    if name == "dtd":
 | 
						|
        return xmlDtd(_obj=o)
 | 
						|
    return xmlNode(_obj=o)
 | 
						|
 | 
						|
def xpathObjectRet(o):
 | 
						|
    otype = type(o)
 | 
						|
    if otype == type([]):
 | 
						|
        ret = list(map(xpathObjectRet, o))
 | 
						|
        return ret
 | 
						|
    elif otype == type(()):
 | 
						|
        ret = list(map(xpathObjectRet, o))
 | 
						|
        return tuple(ret)
 | 
						|
    elif otype == type('') or otype == type(0) or otype == type(0.0):
 | 
						|
        return o
 | 
						|
    else:
 | 
						|
        return nodeWrap(o)
 | 
						|
 | 
						|
#
 | 
						|
# register an XPath function
 | 
						|
#
 | 
						|
def registerXPathFunction(ctxt, name, ns_uri, f):
 | 
						|
    ret = libxml2mod.xmlRegisterXPathFunction(ctxt, name, ns_uri, f)
 | 
						|
 | 
						|
#
 | 
						|
# For the xmlTextReader parser configuration
 | 
						|
#
 | 
						|
PARSER_LOADDTD=1
 | 
						|
PARSER_DEFAULTATTRS=2
 | 
						|
PARSER_VALIDATE=3
 | 
						|
PARSER_SUBST_ENTITIES=4
 | 
						|
 | 
						|
#
 | 
						|
# For the error callback severities
 | 
						|
#
 | 
						|
PARSER_SEVERITY_VALIDITY_WARNING=1
 | 
						|
PARSER_SEVERITY_VALIDITY_ERROR=2
 | 
						|
PARSER_SEVERITY_WARNING=3
 | 
						|
PARSER_SEVERITY_ERROR=4
 | 
						|
 | 
						|
#
 | 
						|
# register the libxml2 error handler
 | 
						|
#
 | 
						|
def registerErrorHandler(f, ctx):
 | 
						|
    """Register a Python written function to for error reporting.
 | 
						|
       The function is called back as f(ctx, error). """
 | 
						|
    import sys
 | 
						|
    if 'libxslt' not in sys.modules:
 | 
						|
        # normal behaviour when libxslt is not imported
 | 
						|
        ret = libxml2mod.xmlRegisterErrorHandler(f,ctx)
 | 
						|
    else:
 | 
						|
        # when libxslt is already imported, one must
 | 
						|
        # use libxst's error handler instead
 | 
						|
        import libxslt
 | 
						|
        ret = libxslt.registerErrorHandler(f,ctx)
 | 
						|
    return ret
 | 
						|
 | 
						|
class parserCtxtCore:
 | 
						|
 | 
						|
    def __init__(self, _obj=None):
 | 
						|
        if _obj != None: 
 | 
						|
            self._o = _obj;
 | 
						|
            return
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlFreeParserCtxt(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def setErrorHandler(self,f,arg):
 | 
						|
        """Register an error handler that will be called back as
 | 
						|
           f(arg,msg,severity,reserved).
 | 
						|
           
 | 
						|
           @reserved is currently always None."""
 | 
						|
        libxml2mod.xmlParserCtxtSetErrorHandler(self._o,f,arg)
 | 
						|
 | 
						|
    def getErrorHandler(self):
 | 
						|
        """Return (f,arg) as previously registered with setErrorHandler
 | 
						|
           or (None,None)."""
 | 
						|
        return libxml2mod.xmlParserCtxtGetErrorHandler(self._o)
 | 
						|
 | 
						|
    def addLocalCatalog(self, uri):
 | 
						|
        """Register a local catalog with the parser"""
 | 
						|
        return libxml2mod.addLocalCatalog(self._o, uri)
 | 
						|
    
 | 
						|
 | 
						|
class ValidCtxtCore:
 | 
						|
 | 
						|
    def __init__(self, *args, **kw):
 | 
						|
        pass
 | 
						|
 | 
						|
    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
 | 
						|
        """
 | 
						|
        Register error and warning handlers for DTD validation.
 | 
						|
        These will be called back as f(msg,arg)
 | 
						|
        """
 | 
						|
        libxml2mod.xmlSetValidErrors(self._o, err_func, warn_func, arg)
 | 
						|
    
 | 
						|
 | 
						|
class SchemaValidCtxtCore:
 | 
						|
 | 
						|
    def __init__(self, *args, **kw):
 | 
						|
        pass
 | 
						|
 | 
						|
    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
 | 
						|
        """
 | 
						|
        Register error and warning handlers for Schema validation.
 | 
						|
        These will be called back as f(msg,arg)
 | 
						|
        """
 | 
						|
        libxml2mod.xmlSchemaSetValidErrors(self._o, err_func, warn_func, arg)
 | 
						|
 | 
						|
 | 
						|
class relaxNgValidCtxtCore:
 | 
						|
 | 
						|
    def __init__(self, *args, **kw):
 | 
						|
        pass
 | 
						|
 | 
						|
    def setValidityErrorHandler(self, err_func, warn_func, arg=None):
 | 
						|
        """
 | 
						|
        Register error and warning handlers for RelaxNG validation.
 | 
						|
        These will be called back as f(msg,arg)
 | 
						|
        """
 | 
						|
        libxml2mod.xmlRelaxNGSetValidErrors(self._o, err_func, warn_func, arg)
 | 
						|
 | 
						|
    
 | 
						|
def _xmlTextReaderErrorFunc(xxx_todo_changeme,msg,severity,locator):
 | 
						|
    """Intermediate callback to wrap the locator"""
 | 
						|
    (f,arg) = xxx_todo_changeme
 | 
						|
    return f(arg,msg,severity,xmlTextReaderLocator(locator))
 | 
						|
 | 
						|
class xmlTextReaderCore:
 | 
						|
 | 
						|
    def __init__(self, _obj=None):
 | 
						|
        self.input = None
 | 
						|
        if _obj != None:self._o = _obj;return
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def __del__(self):
 | 
						|
        if self._o != None:
 | 
						|
            libxml2mod.xmlFreeTextReader(self._o)
 | 
						|
        self._o = None
 | 
						|
 | 
						|
    def SetErrorHandler(self,f,arg):
 | 
						|
        """Register an error handler that will be called back as
 | 
						|
           f(arg,msg,severity,locator)."""
 | 
						|
        if f is None:
 | 
						|
            libxml2mod.xmlTextReaderSetErrorHandler(\
 | 
						|
                self._o,None,None)
 | 
						|
        else:
 | 
						|
            libxml2mod.xmlTextReaderSetErrorHandler(\
 | 
						|
                self._o,_xmlTextReaderErrorFunc,(f,arg))
 | 
						|
 | 
						|
    def GetErrorHandler(self):
 | 
						|
        """Return (f,arg) as previously registered with setErrorHandler
 | 
						|
           or (None,None)."""
 | 
						|
        f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)
 | 
						|
        if f is None:
 | 
						|
            return None,None
 | 
						|
        else:
 | 
						|
            # assert f is _xmlTextReaderErrorFunc
 | 
						|
            return arg
 | 
						|
 | 
						|
#
 | 
						|
# The cleanup now goes though a wrapper in libxml.c
 | 
						|
#
 | 
						|
def cleanupParser():
 | 
						|
    libxml2mod.xmlPythonCleanupParser()
 | 
						|
 | 
						|
#
 | 
						|
# The interface to xmlRegisterInputCallbacks.
 | 
						|
# Since this API does not allow to pass a data object along with
 | 
						|
# match/open callbacks, it is necessary to maintain a list of all
 | 
						|
# Python callbacks.
 | 
						|
#
 | 
						|
__input_callbacks = []
 | 
						|
def registerInputCallback(func):
 | 
						|
    def findOpenCallback(URI):
 | 
						|
        for cb in reversed(__input_callbacks):
 | 
						|
            o = cb(URI)
 | 
						|
            if o is not None:
 | 
						|
                return o
 | 
						|
    libxml2mod.xmlRegisterInputCallback(findOpenCallback)
 | 
						|
    __input_callbacks.append(func)
 | 
						|
 | 
						|
def popInputCallbacks():
 | 
						|
    # First pop python-level callbacks, when no more available - start
 | 
						|
    # popping built-in ones.
 | 
						|
    if len(__input_callbacks) > 0:
 | 
						|
        __input_callbacks.pop()
 | 
						|
    if len(__input_callbacks) == 0:
 | 
						|
        libxml2mod.xmlUnregisterInputCallback()
 | 
						|
 | 
						|
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 | 
						|
#
 | 
						|
# Everything before this line comes from libxml.py 
 | 
						|
# Everything after this line is automatically generated
 | 
						|
#
 | 
						|
# WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
 | 
						|
 |