#
# 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