xmlifDom.py
Go to the documentation of this file.
00001 #
00002 # genxmlif, Release 0.9.0
00003 # file: xmlifDom.py
00004 #
00005 # XML interface base class for Python DOM implementations
00006 #
00007 # history:
00008 # 2005-04-25 rl   created
00009 # 2007-07-02 rl   complete re-design, internal wrapper 
00010 #                 for DOM trees and elements introduced
00011 # 2008-07-01 rl   Limited support of XInclude added
00012 #
00013 # Copyright (c) 2005-2008 by Roland Leuthe.  All rights reserved.
00014 #
00015 # --------------------------------------------------------------------
00016 # The generic XML interface is
00017 #
00018 # Copyright (c) 2005-2008 by Roland Leuthe
00019 #
00020 # By obtaining, using, and/or copying this software and/or its
00021 # associated documentation, you agree that you have read, understood,
00022 # and will comply with the following terms and conditions:
00023 #
00024 # Permission to use, copy, modify, and distribute this software and
00025 # its associated documentation for any purpose and without fee is
00026 # hereby granted, provided that the above copyright notice appears in
00027 # all copies, and that both that copyright notice and this permission
00028 # notice appear in supporting documentation, and that the name of
00029 # the author not be used in advertising or publicity
00030 # pertaining to distribution of the software without specific, written
00031 # prior permission.
00032 #
00033 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
00034 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
00035 # ABILITY AND FITNESS.  IN NO EVENT SHALL THE AUTHOR
00036 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
00037 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00038 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00039 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
00040 # OF THIS SOFTWARE.
00041 # --------------------------------------------------------------------
00042 
00043 import string
00044 import copy
00045 import urllib
00046 from types                import TupleType
00047 from xml.dom              import Node, getDOMImplementation, XMLNS_NAMESPACE
00048 from ..genxmlif             import XINC_NAMESPACE, GenXmlIfError
00049 from xmlifUtils           import nsNameToQName, processWhitespaceAction, collapseString, NsNameTupleFactory, convertToAbsUrl
00050 from xmlifBase            import XmlIfBuilderExtensionBase
00051 from xmlifApi             import XmlInterfaceBase
00052 
00053 
00054 class XmlInterfaceDom (XmlInterfaceBase):
00055     """Derived interface class for handling of DOM parsers.
00056     
00057     For description of the interface methods see xmlifbase.py.
00058     """
00059     
00060     def xInclude (self, elementWrapper, baseUrl, ownerDoc):
00061         filePath = elementWrapper.getFilePath()
00062         for childElementWrapper in elementWrapper.getChildren():
00063             line = childElementWrapper.getStartLineNumber()
00064             if childElementWrapper.getNsName() == (XINC_NAMESPACE, "include"):
00065                 href = childElementWrapper["href"]
00066                 parse = childElementWrapper.getAttributeOrDefault ("parse", "xml")
00067                 encoding = childElementWrapper.getAttribute ("encoding")
00068                 if self.verbose:
00069                     print "Xinclude: %s" %href
00070                 try:
00071                     if parse == "xml":
00072                         subTreeWrapper = self.parse (href, baseUrl, ownerDoc)
00073                         elementWrapper.replaceChildBySubtree (childElementWrapper, subTreeWrapper)
00074                     elif parse == "text":
00075                         absUrl = convertToAbsUrl (href, baseUrl)
00076                         fp = urllib.urlopen (absUrl)
00077                         data = fp.read()
00078                         if encoding:
00079                             data = data.decode(encoding)
00080                         newTextNode = ownerDoc.xmlIfExtCreateTextNode(data)
00081                         elementWrapper.element.element.insertBefore (newTextNode, childElementWrapper.element.element)
00082                         elementWrapper.removeChild (childElementWrapper)
00083                         fp.close()
00084                     else:
00085                         raise GenXmlIfError, "%s: line %s: XIncludeError: Invalid 'parse' Attribut: '%s'" %(filePath, line, parse)
00086                 except IOError, errInst:
00087                     raise GenXmlIfError, "%s: line %s: IOError: %s" %(filePath, line, str(errInst))
00088             elif childElementWrapper.getNsName() == (XINC_NAMESPACE, "fallback"):
00089                 raise GenXmlIfError, "%s: line %s: XIncludeError: xi:fallback tag must be child of xi:include" %(filePath, line)
00090             else:
00091                 self.xInclude(childElementWrapper, baseUrl, ownerDoc)
00092 
00093 
00094 
00095 class InternalDomTreeWrapper:
00096     """Internal wrapper for a DOM Document class.
00097     """
00098     def __init__ (self, document):
00099         self.document   = document
00100     
00101     def xmlIfExtGetRootNode (self):
00102         domNode = self.document
00103         if domNode.nodeType == Node.DOCUMENT_NODE:
00104             return domNode.documentElement.xmlIfExtInternalWrapper
00105         elif domNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
00106             for node in domNode.childNodes:
00107                 if node.nodeType == Node.ELEMENT_NODE:
00108                     return node.xmlIfExtInternalWrapper
00109             else:
00110                 return None
00111         else:
00112             return None
00113 
00114 
00115     def xmlIfExtCreateElement (self, nsName, attributeDict, curNs):
00116         elementNode = self.document.createElementNS (nsName[0], nsName[1])
00117         intElementWrapper = self.internalElementWrapperClass(elementNode, self)
00118         for attrName, attrValue in attributeDict.items():
00119             intElementWrapper.xmlIfExtSetAttribute (NsNameTupleFactory(attrName), attrValue, curNs)
00120         return intElementWrapper
00121 
00122 
00123     def xmlIfExtCreateTextNode (self, data):
00124         return self.document.createTextNode(data)
00125     
00126 
00127     def xmlIfExtImportNode (self, node):
00128         return self.document.importNode (node, 0) 
00129         
00130 
00131     def xmlIfExtCloneTree (self, rootElementCopy):
00132         domImpl = getDOMImplementation()
00133 #        documentCopy = domImpl.createDocument(rootElementCopy.xmlIfExtGetNamespaceURI(), rootElementCopy.xmlIfExtGetTagName(), None)
00134         documentCopy = domImpl.createDocument(None, None, None)
00135 #        documentCopy = copy.copy(self.document)
00136         documentCopy.documentElement = rootElementCopy.element
00137         return self.__class__(documentCopy)
00138 
00139     
00140 
00141 #########################################################
00142 # Internal Wrapper class for a Dom Element class
00143 
00144 class InternalDomElementWrapper:
00145     """Internal Wrapper for a Dom Element class.
00146     """
00147     
00148     def __init__ (self, element, internalDomTreeWrapper):
00149         self.element = element
00150         element.xmlIfExtInternalWrapper = self
00151         self.internalDomTreeWrapper = internalDomTreeWrapper
00152         
00153 
00154     def xmlIfExtUnlink (self):
00155         self.xmlIfExtElementWrapper = None
00156         
00157 
00158     def xmlIfExtCloneNode (self):
00159         nodeCopy = self.__class__(self.element.cloneNode(deep=0), self.internalDomTreeWrapper)
00160         for childTextNode in self.__xmlIfExtGetChildTextNodes():
00161             childTextNodeCopy = childTextNode.cloneNode(0)
00162             nodeCopy.element.appendChild (childTextNodeCopy)
00163 #        for nsAttrName, attrValue in self.xmlIfExtGetAttributeDict().items():
00164 #            nodeCopy.xmlIfExtSetAttribute(nsAttrName, attrValue, self.xmlIfExtElementWrapper.getCurrentNamespaces())
00165         return nodeCopy
00166 
00167     
00168     def xmlIfExtGetTagName (self):
00169         return self.element.tagName
00170 
00171 
00172     def xmlIfExtGetNamespaceURI (self):
00173         return self.element.namespaceURI
00174 
00175 
00176     def xmlIfExtGetParentNode (self):
00177         parentNode = self.element.parentNode
00178         if parentNode.nodeType == Node.ELEMENT_NODE:
00179             return self.element.parentNode.xmlIfExtInternalWrapper
00180         else:
00181             return None
00182 
00183     
00184     def xmlIfExtSetParentNode (self, parentElement):
00185         pass # nothing to do since parent is provided by DOM interface
00186     
00187 
00188     def xmlIfExtGetChildren (self, tagFilter=None):
00189         # TODO: Handle also wildcard tagFilter = (namespace, None)
00190         children = filter (lambda e: (e.nodeType == Node.ELEMENT_NODE) and          # - only ELEMENTs
00191                                       (tagFilter == None or 
00192                                        (e.namespaceURI == tagFilter[0] and e.localName == tagFilter[1])), # - if tagFilter given --> check
00193                            self.element.childNodes )                                 # from element's nodes
00194 
00195         return map(lambda element: element.xmlIfExtInternalWrapper, children)
00196 
00197 
00198     def xmlIfExtGetFirstChild (self, tagFilter=None):
00199         children = self.xmlIfExtGetChildren (tagFilter)
00200         if children != []:
00201             return children[0]
00202         else:
00203             None
00204 
00205 
00206     def xmlIfExtGetElementsByTagName (self, tagFilter=('*','*')):
00207         elementList = self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] )
00208         return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
00209 
00210 
00211     def xmlIfExtGetIterator (self, tagFilter=('*','*')):
00212         elementList = []
00213         if tagFilter in (('*','*'), (self.element.namespaceURI, self.element.localName)):
00214             elementList.append(self.element)
00215         elementList.extend(self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] ))
00216         return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
00217 
00218     
00219     def xmlIfExtAppendChild (self, childElement):
00220         self.element.appendChild (childElement.element)
00221 
00222 
00223     def xmlIfExtInsertBefore (self, childElement, refChildElement):
00224         self.element.insertBefore (childElement.element, refChildElement.element)
00225 
00226 
00227     def xmlIfExtRemoveChild (self, childElement):
00228         self.element.removeChild (childElement.element)
00229 
00230 
00231     def xmlIfExtInsertSubtree (self, refChildElement, subTree, insertSubTreeRootNode):
00232         if insertSubTreeRootNode:
00233             childElementList = [subTree.xmlIfExtGetRootNode(),]
00234         else:
00235             childElementList = subTree.xmlIfExtGetRootNode().xmlIfExtGetChildren()
00236 
00237         for childElement in childElementList:
00238             if refChildElement != None:
00239                 self.element.insertBefore(childElement.element, refChildElement.element)
00240             else:
00241                 self.element.appendChild(childElement.element)
00242 
00243 
00244     def xmlIfExtGetAttributeDict (self):
00245         attribDict = {}
00246         for nsAttrName, attrNodeOrValue in self.element.attributes.items():
00247             attribDict[NsNameTupleFactory(nsAttrName)] = attrNodeOrValue.nodeValue
00248         return attribDict
00249 
00250 
00251     def xmlIfExtGetAttribute (self, nsAttrName):
00252         if self.element.attributes.has_key (nsAttrName):
00253             return self.element.getAttributeNS (nsAttrName[0], nsAttrName[1])
00254         elif nsAttrName[1] == "xmlns" and self.element.attributes.has_key(nsAttrName[1]):
00255             # workaround for minidom for correct access of xmlns attribute
00256             return self.element.getAttribute (nsAttrName[1])
00257         else:
00258             return None
00259 
00260 
00261     def xmlIfExtSetAttribute (self, nsAttrName, attributeValue, curNs):
00262         if nsAttrName[0] != None:
00263             qName = nsNameToQName (nsAttrName, curNs)
00264         else:
00265             qName = nsAttrName[1]
00266         
00267         self.element.setAttributeNS (nsAttrName[0], qName, attributeValue)
00268 
00269 
00270     def xmlIfExtRemoveAttribute (self, nsAttrName):
00271         self.element.removeAttributeNS (nsAttrName[0], nsAttrName[1])
00272 
00273 
00274     def xmlIfExtGetElementValueFragments (self, ignoreEmtpyStringFragments):
00275         elementValueList = []
00276         for childTextNode in self.__xmlIfExtGetChildTextNodes():
00277             elementValueList.append(childTextNode.data)
00278         if ignoreEmtpyStringFragments:
00279             elementValueList = filter (lambda s: collapseString(s) != "", elementValueList)
00280         if elementValueList == []:
00281             elementValueList = ["",]
00282         return elementValueList
00283 
00284 
00285     def xmlIfExtGetElementText (self):
00286         elementTextList = ["",]
00287         if self.element.childNodes != []:
00288             for childNode in self.element.childNodes:
00289                 if childNode.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
00290                     elementTextList.append (childNode.data)
00291                 else:
00292                     break
00293         return "".join(elementTextList)
00294 
00295     
00296     def xmlIfExtGetElementTailText (self):
00297         tailTextList = ["",]
00298         nextSib = self.element.nextSibling
00299         while nextSib:
00300             if nextSib.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
00301                 tailTextList.append (nextSib.data)
00302                 nextSib = nextSib.nextSibling
00303             else:
00304                 break
00305         return "".join(tailTextList)
00306         
00307 
00308     def xmlIfExtSetElementValue (self, elementValue):
00309         if self.__xmlIfExtGetChildTextNodes() == []:
00310             textNode = self.internalDomTreeWrapper.xmlIfExtCreateTextNode (elementValue)
00311             self.element.appendChild (textNode)
00312         else:
00313             self.__xmlIfExtGetChildTextNodes()[0].data = elementValue
00314             if len (self.__xmlIfExtGetChildTextNodes()) > 1:
00315                 for textNode in self.__xmlIfExtGetChildTextNodes()[1:]:
00316                     textNode.data = ""
00317             
00318 
00319     def xmlIfExtProcessWsElementValue (self, wsAction):
00320         textNodes = self.__xmlIfExtGetChildTextNodes()
00321 
00322         if len(textNodes) == 1:
00323             textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction)
00324         elif len(textNodes) > 1:
00325             textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction, rstrip=0)
00326             lstrip = 0
00327             if len(textNodes[0].data) > 0 and textNodes[0].data[-1] == " ":
00328                 lstrip = 1
00329             for textNode in textNodes[1:-1]:
00330                 textNode.data = processWhitespaceAction (textNode.data, wsAction, lstrip, rstrip=0)
00331                 if len(textNode.data) > 0 and textNode.data[-1] == " ":
00332                     lstrip = 1
00333                 else:
00334                     lstrip = 0
00335             textNodes[-1].data = processWhitespaceAction (textNodes[-1].data, wsAction, lstrip)
00336 
00337 
00338     ###############################################################
00339     # PRIVATE methods
00340     ###############################################################
00341 
00342     def __xmlIfExtGetChildTextNodes ( self ):
00343         """Return list of TEXT nodes."""
00344         return filter (lambda e: ( e.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE) ), # - only TEXT-NODES
00345                        self.element.childNodes)                         # from element's child nodes
00346         
00347 
00348 
00349 class XmlIfBuilderExtensionDom (XmlIfBuilderExtensionBase):
00350     """XmlIf builder extension class for DOM parsers."""
00351     
00352     pass


mavlink
Author(s): Lorenz Meier
autogenerated on Thu Jun 6 2019 19:01:57