import libxml2modimport typesimport sys# The root of all libxml2 errors.class libxmlError(Exception): pass# Type of the wrapper class for the C objects wrappersdef checkWrapper(obj):try:n = type(_obj).__name__if n != 'PyCObject' and n != 'PyCapsule':return 1except:return 0return 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 = msgdef __str__(self):return self.msgclass parserError(libxmlError):def __init__(self, msg):self.msg = msgdef __str__(self):return self.msgclass uriError(libxmlError):def __init__(self, msg):self.msg = msgdef __str__(self):return self.msgclass xpathError(libxmlError):def __init__(self, msg):self.msg = msgdef __str__(self):return self.msgclass ioWrapper:def __init__(self, _obj):self.__io = _objself._o = Nonedef io_close(self):if self.__io == None:return(-1)self.__io.close()self.__io = Nonereturn(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 syse = sys.exc_info()[1]print("failed to read from Python:", type(e))print("on IO:", self.__io)self.__io == Nonereturn(-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 = Nonedef close(self):self.io_close()if self._o != None:libxml2mod.xmlFreeParserInputBuffer(self._o)self._o = Noneclass ioWriteWrapper(ioWrapper):def __init__(self, _obj, enc = ""):# print "ioWriteWrapper.__init__", _objif type(_obj) == type(''):print("write io from a string")self.o = Noneelif 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 = _objdef __del__(self):# print "__del__"self.io_close()if self._o != None:libxml2mod.xmlOutputBufferClose(self._o)self._o = Nonedef flush(self):self.io_flush()if self._o != None:libxml2mod.xmlOutputBufferClose(self._o)self._o = Nonedef 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"""passdef endDocument(self):"""called at the end of the document"""passdef startElement(self, tag, attrs):"""called at the start of every element, tag is the name ofthe element, attrs is a dictionary of the element's attributes"""passdef endElement(self, tag):"""called at the start of every element, tag is the name ofthe element"""passdef characters(self, data):"""called when character data have been read, data is the stringcontaining the data, multiple consecutive characters() callbackare possible."""passdef cdataBlock(self, data):"""called when CDATA section have been read, data is the stringcontaining the data, multiple consecutive cdataBlock() callbackare possible."""passdef reference(self, name):"""called when an entity reference has been found"""passdef ignorableWhitespace(self, data):"""called when potentially ignorable white spaces have been found"""passdef processingInstruction(self, target, data):"""called when a PI has been found, target contains the PI name anddata is the associated data in the PI"""passdef comment(self, content):"""called when a comment has been found, content contains the comment"""passdef externalSubset(self, name, externalID, systemID):"""called when a DOCTYPE declaration has been found, name is theDTD name and externalID, systemID are the DTD public and systemidentifier for that DTd if available"""passdef internalSubset(self, name, externalID, systemID):"""called when a DOCTYPE declaration has been found, name is theDTD name and externalID, systemID are the DTD public and systemidentifier for that DTD if available"""passdef entityDecl(self, name, type, externalID, systemID, content):"""called when an ENTITY declaration has been found, name is theentity name and externalID, systemID are the entity public andsystem identifier for that entity if available, type indicatesthe entity type, and content reports it's string content"""passdef notationDecl(self, name, externalID, systemID):"""called when an NOTATION declaration has been found, name is thenotation name and externalID, systemID are the notation public andsystem identifier for that notation if available"""passdef attributeDecl(self, elem, name, type, defi, defaultValue, nameList):"""called when an ATTRIBUTE definition has been found"""passdef elementDecl(self, name, type, content):"""called when an ELEMENT definition has been found"""passdef 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 entitypublic and system identifier for that entity if available,and notationName indicate the associated NOTATION"""passdef warning(self, msg):#print msgpassdef 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;returnself._o = Nonedef __eq__(self, other):if other == None:return Falseret = libxml2mod.compareNodesEqual(self._o, other._o)if ret == None:return Falsereturn ret == Truedef __ne__(self, other):if other == None:return Trueret = libxml2mod.compareNodesEqual(self._o, other._o)return not retdef __hash__(self):ret = libxml2mod.nodeHash(self._o)return retdef __str__(self):return self.serialize()def get_parent(self):ret = libxml2mod.parent(self._o)if ret == None:return Nonereturn nodeWrap(ret)def get_children(self):ret = libxml2mod.children(self._o)if ret == None:return Nonereturn nodeWrap(ret)def get_last(self):ret = libxml2mod.last(self._o)if ret == None:return Nonereturn nodeWrap(ret)def get_next(self):ret = libxml2mod.next(self._o)if ret == None:return Nonereturn nodeWrap(ret)def get_properties(self):ret = libxml2mod.properties(self._o)if ret == None:return Nonereturn xmlAttr(_obj=ret)def get_prev(self):ret = libxml2mod.prev(self._o)if ret == None:return Nonereturn 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 Nonereturn xmlDoc(_obj=ret)## Those are common attributes to nearly all type of nodes# defined as python2 properties#import sysif float(sys.version[0:3]) < 2.2:def __getattr__(self, attr):if attr == "parent":ret = libxml2mod.parent(self._o)if ret == None:return Nonereturn nodeWrap(ret)elif attr == "properties":ret = libxml2mod.properties(self._o)if ret == None:return Nonereturn xmlAttr(_obj=ret)elif attr == "children":ret = libxml2mod.children(self._o)if ret == None:return Nonereturn nodeWrap(ret)elif attr == "last":ret = libxml2mod.last(self._o)if ret == None:return Nonereturn nodeWrap(ret)elif attr == "next":ret = libxml2mod.next(self._o)if ret == None:return Nonereturn nodeWrap(ret)elif attr == "prev":ret = libxml2mod.prev(self._o)if ret == None:return Nonereturn 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 Nonereturn 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.docif doc == None:return Nonectxt = 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 resdef xpathEval2(self, expr):return self.xpathEval(expr)# Remove namespacesdef removeNsDef(self, href):"""Remove a namespace definition from a node. If href is None,remove all of the ns definitions on that node. The removednamespaces 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 callrenconciliateNs() to fix those pointers.Note: This method does not free memory taken by the nsdefinitions. You will need to free it manually with thefreeNsList() 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 iteratorsdef walk_depth_first(self):return xmlCoreDepthFirstItertor(self)def walk_breadth_first(self):return xmlCoreBreadthFirstItertor(self)__iter__ = walk_depth_firstdef free(self):try:self.doc._ctxt.xpathFreeContext()except:passlibxml2mod.xmlFreeDoc(self._o)## implements the depth-first iterator for libxml2 DOM tree#class xmlCoreDepthFirstItertor:def __init__(self, node):self.node = nodeself.parents = []def __iter__(self):return selfdef __next__(self):while 1:if self.node:ret = self.nodeself.parents.append(self.node)self.node = self.node.childrenreturn rettry:parent = self.parents.pop()except IndexError:raise StopIterationself.node = parent.nextnext = __next__## implements the breadth-first iterator for libxml2 DOM tree#class xmlCoreBreadthFirstItertor:def __init__(self, node):self.node = nodeself.parents = []def __iter__(self):return selfdef __next__(self):while 1:if self.node:ret = self.nodeself.parents.append(self.node)self.node = self.node.nextreturn rettry:parent = self.parents.pop()except IndexError:raise StopIterationself.node = parent.childrennext = __next__## converters to present a nicer view of the XPath returns#def nodeWrap(o):# TODO try to cast to the most appropriate node classname = 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 retelif otype == type(()):ret = list(map(xpathObjectRet, o))return tuple(ret)elif otype == type('') or otype == type(0) or otype == type(0.0):return oelse: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=1PARSER_DEFAULTATTRS=2PARSER_VALIDATE=3PARSER_SUBST_ENTITIES=4## For the error callback severities#PARSER_SEVERITY_VALIDITY_WARNING=1PARSER_SEVERITY_VALIDITY_ERROR=2PARSER_SEVERITY_WARNING=3PARSER_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 sysif 'libxslt' not in sys.modules:# normal behaviour when libxslt is not importedret = libxml2mod.xmlRegisterErrorHandler(f,ctx)else:# when libxslt is already imported, one must# use libxst's error handler insteadimport libxsltret = libxslt.registerErrorHandler(f,ctx)return retclass parserCtxtCore:def __init__(self, _obj=None):if _obj != None:self._o = _obj;returnself._o = Nonedef __del__(self):if self._o != None:libxml2mod.xmlFreeParserCtxt(self._o)self._o = Nonedef setErrorHandler(self,f,arg):"""Register an error handler that will be called back asf(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 setErrorHandleror (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):passdef 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):passdef 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):passdef 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_changemereturn f(arg,msg,severity,xmlTextReaderLocator(locator))class xmlTextReaderCore:def __init__(self, _obj=None):self.input = Noneif _obj != None:self._o = _obj;returnself._o = Nonedef __del__(self):if self._o != None:libxml2mod.xmlFreeTextReader(self._o)self._o = Nonedef SetErrorHandler(self,f,arg):"""Register an error handler that will be called back asf(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 setErrorHandleror (None,None)."""f,arg = libxml2mod.xmlTextReaderGetErrorHandler(self._o)if f is None:return None,Noneelse:# assert f is _xmlTextReaderErrorFuncreturn 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 olibxml2mod.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()## Deprecated#def dumpMemory():"""DEPRECATED: This feature was removed."""# 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
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。