etisserant@0: # etisserant@0: # minixsv, Release 0.3 etisserant@0: # file: elemtreeif.py etisserant@0: # etisserant@0: # XML interface class to elementtree toolkit by Fredrik Lundh etisserant@0: # etisserant@0: # history: etisserant@0: # 2004-09-09 rl created etisserant@0: # 2004-09-22 rl XML interface classes completely re-designed etisserant@0: # 2004-09-23 rl added filename and line number support etisserant@0: # 2004-09-29 rl URL processing added etisserant@0: # 2004-10-01 rl URL processing improved etisserant@0: # 2004-10-12 rl XML text processing added etisserant@0: # etisserant@0: # Copyright (c) 2004 by Roland Leuthe. All rights reserved. etisserant@0: # etisserant@0: # -------------------------------------------------------------------- etisserant@0: # The minixsv XML schema validator is etisserant@0: # etisserant@0: # Copyright (c) 2004 by Roland Leuthe etisserant@0: # etisserant@0: # By obtaining, using, and/or copying this software and/or its etisserant@0: # associated documentation, you agree that you have read, understood, etisserant@0: # and will comply with the following terms and conditions: etisserant@0: # etisserant@0: # Permission to use, copy, modify, and distribute this software and etisserant@0: # its associated documentation for any purpose and without fee is etisserant@0: # hereby granted, provided that the above copyright notice appears in etisserant@0: # all copies, and that both that copyright notice and this permission etisserant@0: # notice appear in supporting documentation, and that the name of etisserant@0: # the author not be used in advertising or publicity etisserant@0: # pertaining to distribution of the software without specific, written etisserant@0: # prior permission. etisserant@0: # etisserant@0: # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD etisserant@0: # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- etisserant@0: # ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR etisserant@0: # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY etisserant@0: # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, etisserant@0: # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS etisserant@0: # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE etisserant@0: # OF THIS SOFTWARE. etisserant@0: # -------------------------------------------------------------------- etisserant@0: etisserant@0: etisserant@0: import urllib etisserant@0: import urlparse etisserant@0: from xmlifbase import * etisserant@0: from xml.parsers.expat import ExpatError etisserant@0: from elementtree.ElementTree import * etisserant@0: etisserant@0: ######################################################### etisserant@0: # Derived interface class for elementtree toolkit etisserant@0: etisserant@0: class ElementTreeInterface (XmlInterfaceBase): etisserant@0: ##################################################### etisserant@0: # for description of the interface methods see xmlifbase.py etisserant@0: ##################################################### etisserant@0: etisserant@0: def __init__ (self, verbose): etisserant@0: XmlInterfaceBase.__init__ (self, verbose) etisserant@0: if self.verbose: etisserant@0: print "Using elementtree interface module..." etisserant@0: etisserant@0: etisserant@0: def parse (self, file, baseUrl): etisserant@0: url = self._convertToUrl(file) etisserant@0: absUrl = self._convertToAbsUrl (url, baseUrl) etisserant@0: fp = urllib.urlopen (absUrl) etisserant@0: try: etisserant@0: tree = ElementTree() etisserant@0: parser = ExtXMLTreeBuilder(file, url, absUrl) etisserant@0: tree.parse(fp, parser) etisserant@0: finally: etisserant@0: fp.close() etisserant@0: etisserant@0: return TreeWrapper(self, tree) etisserant@0: etisserant@0: etisserant@0: def parseString (self, text): etisserant@0: parser = ExtXMLTreeBuilder("", "", "") etisserant@0: parser.feed(text) etisserant@0: return TreeWrapper (self, ElementTree(parser.close())) etisserant@0: etisserant@0: etisserant@0: ######################################################### etisserant@0: # Wrapper class for ElementTree class etisserant@0: etisserant@0: class TreeWrapper (TreeWrapperBase): etisserant@0: etisserant@0: def getRootNode (self): etisserant@0: return ElementWrapper(self.xmlIf, self, self.tree.getroot()) etisserant@0: etisserant@0: etisserant@0: def insertSubtree (self, nextSiblingWrapper, file, baseUrl): etisserant@0: subTreeWrapper = self.xmlIf.extParse (file, baseUrl) etisserant@0: assert self.getRootNode().getTagName() == subTreeWrapper.getRootNode().getTagName(),\ etisserant@0: "%s: line %d: root node of include file %s does not match!" %(self.getRootNode().getUrl(), self.getRootNode().getStartLineNumber(), file) etisserant@0: etisserant@0: if nextSiblingWrapper != None: etisserant@0: insertIndex = self.tree.getroot().getchildren().index (nextSiblingWrapper.element) etisserant@0: else: etisserant@0: insertIndex = 0 etisserant@0: elementWrapperList = subTreeWrapper.getRootNode().getChildren() etisserant@0: elementWrapperList.reverse() etisserant@0: for elementWrapper in elementWrapperList: etisserant@0: self.tree.getroot().insert (insertIndex, elementWrapper.element) etisserant@0: etisserant@0: etisserant@0: ######################################################### etisserant@0: # Wrapper class for Element class etisserant@0: etisserant@0: class ElementWrapper (ElementWrapperBase): etisserant@0: etisserant@0: def getTagName (self): etisserant@0: return self.element.tag etisserant@0: etisserant@0: etisserant@0: def getChildren (self, filterTag=None): etisserant@0: if filterTag in (None, '*'): etisserant@0: children = self.element.getchildren() etisserant@0: else: etisserant@0: children = self.element.findall(filterTag) etisserant@0: etisserant@0: return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), children) etisserant@0: etisserant@0: etisserant@0: def getFirstChild (self, filterTag=None): etisserant@0: # replace base method (performance optimized) etisserant@0: if filterTag in (None, '*'): etisserant@0: children = self.element.getchildren() etisserant@0: if children != []: etisserant@0: element = children[0] etisserant@0: else: etisserant@0: element = None etisserant@0: else: etisserant@0: element = self.element.find(filterTag) etisserant@0: etisserant@0: if element != None: etisserant@0: return ElementWrapper(self.xmlIf, self.treeWrapper, element) etisserant@0: else: etisserant@0: return None etisserant@0: etisserant@0: etisserant@0: def getElementsByTagName (self, filterTag=None): etisserant@0: if filterTag == '*': etisserant@0: filterTag = None etisserant@0: elements = self.element.getiterator (filterTag) etisserant@0: etisserant@0: return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), elements) etisserant@0: etisserant@0: etisserant@0: def removeChild (self, childElementWrapper): etisserant@0: self.element.remove (childElementWrapper.element) etisserant@0: etisserant@0: etisserant@0: def getAttributeDict (self): etisserant@0: return self.element.attrib etisserant@0: etisserant@0: etisserant@0: def getAttribute (self, attributeName): etisserant@0: if self.element.attrib.has_key(attributeName): etisserant@0: return self.element.attrib[attributeName] etisserant@0: else: etisserant@0: return None etisserant@0: etisserant@0: etisserant@0: def hasAttribute (self, attributeName): etisserant@0: return self.element.attrib.has_key(attributeName) etisserant@0: etisserant@0: etisserant@0: def setAttribute (self, attributeName, attributeValue): etisserant@0: self.element.attrib[attributeName] = attributeValue etisserant@0: etisserant@0: etisserant@0: ############################################################### etisserant@0: # Caution! Currently returns only the element value until the first etisserant@0: # child element!! etisserant@0: def getElementValue (self): etisserant@0: if self.element.text != None: etisserant@0: return self.element.text etisserant@0: else: etisserant@0: return "" etisserant@0: etisserant@0: etisserant@0: ############################################################### etisserant@0: # Caution! Currently only sets the element value until the first etisserant@0: # child element!! etisserant@0: def setElementValue (self, value): etisserant@0: self.element.text = value etisserant@0: etisserant@0: etisserant@0: ################################################### etisserant@0: # Element tree builder class derived from XMLTreeBuilder etisserant@0: # extended to store related line numbers in the Element object etisserant@0: etisserant@0: class ExtXMLTreeBuilder (XMLTreeBuilder): etisserant@0: def __init__(self, filePath, url, absUrl): etisserant@0: self.filePath = filePath etisserant@0: self.url = url etisserant@0: self.absUrl = absUrl etisserant@0: XMLTreeBuilder.__init__(self) etisserant@0: etisserant@0: def _start(self, tag, attrib_in): etisserant@0: element = XMLTreeBuilder._start(self, tag, attrib_in) etisserant@0: element.filePath = self.filePath etisserant@0: element.url = self.url etisserant@0: element.absUrl = self.absUrl etisserant@0: element.startLineNumber = self._parser.ErrorLineNumber etisserant@0: return element etisserant@0: etisserant@0: def _end(self, tag): etisserant@0: element = XMLTreeBuilder._end(self, tag) etisserant@0: element.endLineNumber = self._parser.ErrorLineNumber etisserant@0: return element etisserant@0: etisserant@0: