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