minixsv/elemtreeif.py
changeset 0 b622defdfd98
equal deleted inserted replaced
-1:000000000000 0:b622defdfd98
       
     1 #
       
     2 # minixsv, Release 0.3
       
     3 # file: elemtreeif.py
       
     4 #
       
     5 # XML interface class to elementtree toolkit by Fredrik Lundh
       
     6 #
       
     7 # history:
       
     8 # 2004-09-09 rl   created
       
     9 # 2004-09-22 rl   XML interface classes completely re-designed
       
    10 # 2004-09-23 rl   added filename and line number support
       
    11 # 2004-09-29 rl   URL processing added
       
    12 # 2004-10-01 rl   URL processing improved
       
    13 # 2004-10-12 rl   XML text processing added
       
    14 #
       
    15 # Copyright (c) 2004 by Roland Leuthe.  All rights reserved.
       
    16 #
       
    17 # --------------------------------------------------------------------
       
    18 # The minixsv XML schema validator is
       
    19 #
       
    20 # Copyright (c) 2004 by Roland Leuthe
       
    21 #
       
    22 # By obtaining, using, and/or copying this software and/or its
       
    23 # associated documentation, you agree that you have read, understood,
       
    24 # and will comply with the following terms and conditions:
       
    25 #
       
    26 # Permission to use, copy, modify, and distribute this software and
       
    27 # its associated documentation for any purpose and without fee is
       
    28 # hereby granted, provided that the above copyright notice appears in
       
    29 # all copies, and that both that copyright notice and this permission
       
    30 # notice appear in supporting documentation, and that the name of
       
    31 # the author not be used in advertising or publicity
       
    32 # pertaining to distribution of the software without specific, written
       
    33 # prior permission.
       
    34 #
       
    35 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
       
    36 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
       
    37 # ABILITY AND FITNESS.  IN NO EVENT SHALL THE AUTHOR
       
    38 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
       
    39 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
       
    40 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
       
    41 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
       
    42 # OF THIS SOFTWARE.
       
    43 # --------------------------------------------------------------------
       
    44 
       
    45 
       
    46 import urllib
       
    47 import urlparse
       
    48 from xmlifbase               import *
       
    49 from xml.parsers.expat       import ExpatError
       
    50 from elementtree.ElementTree import *
       
    51 
       
    52 #########################################################
       
    53 # Derived interface class for elementtree toolkit
       
    54 
       
    55 class ElementTreeInterface (XmlInterfaceBase):
       
    56     #####################################################
       
    57     # for description of the interface methods see xmlifbase.py
       
    58     #####################################################
       
    59 
       
    60     def __init__ (self, verbose):
       
    61         XmlInterfaceBase.__init__ (self, verbose)
       
    62         if self.verbose:
       
    63             print "Using elementtree interface module..."
       
    64 
       
    65 
       
    66     def parse (self, file, baseUrl):
       
    67         url    = self._convertToUrl(file)
       
    68         absUrl = self._convertToAbsUrl (url, baseUrl)
       
    69         fp     = urllib.urlopen (absUrl)
       
    70         try:
       
    71             tree = ElementTree()
       
    72             parser = ExtXMLTreeBuilder(file, url, absUrl)
       
    73             tree.parse(fp, parser)
       
    74         finally:
       
    75             fp.close()
       
    76 
       
    77         return TreeWrapper(self, tree)
       
    78 
       
    79 
       
    80     def parseString (self, text):
       
    81         parser = ExtXMLTreeBuilder("", "", "")
       
    82         parser.feed(text)
       
    83         return TreeWrapper (self, ElementTree(parser.close()))
       
    84 
       
    85 
       
    86 #########################################################
       
    87 # Wrapper class for ElementTree class
       
    88 
       
    89 class TreeWrapper (TreeWrapperBase):
       
    90 
       
    91     def getRootNode (self):
       
    92         return ElementWrapper(self.xmlIf, self, self.tree.getroot())
       
    93 
       
    94 
       
    95     def insertSubtree (self, nextSiblingWrapper, file, baseUrl):
       
    96         subTreeWrapper = self.xmlIf.extParse (file, baseUrl)
       
    97         assert self.getRootNode().getTagName() == subTreeWrapper.getRootNode().getTagName(),\
       
    98                "%s: line %d: root node of include file %s does not match!" %(self.getRootNode().getUrl(), self.getRootNode().getStartLineNumber(), file)
       
    99 
       
   100         if nextSiblingWrapper != None:
       
   101             insertIndex = self.tree.getroot().getchildren().index (nextSiblingWrapper.element)
       
   102         else:
       
   103             insertIndex = 0
       
   104         elementWrapperList = subTreeWrapper.getRootNode().getChildren()
       
   105         elementWrapperList.reverse()
       
   106         for elementWrapper in elementWrapperList:
       
   107             self.tree.getroot().insert (insertIndex, elementWrapper.element)
       
   108 
       
   109            
       
   110 #########################################################
       
   111 # Wrapper class for Element class
       
   112 
       
   113 class ElementWrapper (ElementWrapperBase):
       
   114 
       
   115     def getTagName (self):
       
   116         return self.element.tag
       
   117 
       
   118 
       
   119     def getChildren (self, filterTag=None):
       
   120         if filterTag in (None, '*'):
       
   121             children = self.element.getchildren()
       
   122         else:
       
   123             children = self.element.findall(filterTag)
       
   124 
       
   125         return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), children)
       
   126 
       
   127 
       
   128     def getFirstChild (self, filterTag=None):
       
   129         # replace base method (performance optimized)
       
   130         if filterTag in (None, '*'):
       
   131             children = self.element.getchildren()
       
   132             if children != []:
       
   133                 element = children[0]
       
   134             else:
       
   135                 element = None
       
   136         else:
       
   137             element = self.element.find(filterTag)
       
   138 
       
   139         if element != None:
       
   140             return ElementWrapper(self.xmlIf, self.treeWrapper, element)
       
   141         else:
       
   142             return None
       
   143 
       
   144 
       
   145     def getElementsByTagName (self, filterTag=None):
       
   146         if filterTag == '*':
       
   147             filterTag = None
       
   148         elements = self.element.getiterator (filterTag)
       
   149 
       
   150         return map(lambda element: ElementWrapper(self.xmlIf, self.treeWrapper, element), elements)
       
   151 
       
   152 
       
   153     def removeChild (self, childElementWrapper):
       
   154         self.element.remove (childElementWrapper.element)
       
   155 
       
   156 
       
   157     def getAttributeDict (self):
       
   158         return self.element.attrib
       
   159 
       
   160 
       
   161     def getAttribute (self, attributeName):
       
   162         if self.element.attrib.has_key(attributeName):
       
   163             return self.element.attrib[attributeName]
       
   164         else:
       
   165             return None
       
   166 
       
   167         
       
   168     def hasAttribute (self, attributeName):
       
   169         return self.element.attrib.has_key(attributeName)
       
   170 
       
   171 
       
   172     def setAttribute (self, attributeName, attributeValue):
       
   173         self.element.attrib[attributeName] = attributeValue
       
   174 
       
   175 
       
   176     ###############################################################
       
   177     # Caution! Currently returns only the element value until the first
       
   178     #          child element!!
       
   179     def getElementValue (self):
       
   180         if self.element.text != None:
       
   181             return self.element.text
       
   182         else:
       
   183             return ""
       
   184 
       
   185 
       
   186     ###############################################################
       
   187     # Caution! Currently only sets the element value until the first
       
   188     #          child element!!
       
   189     def setElementValue (self, value):
       
   190         self.element.text = value
       
   191 
       
   192 
       
   193 ###################################################
       
   194 # Element tree builder class derived from XMLTreeBuilder
       
   195 # extended to store related line numbers in the Element object
       
   196 
       
   197 class ExtXMLTreeBuilder (XMLTreeBuilder):
       
   198     def __init__(self, filePath, url, absUrl):
       
   199         self.filePath = filePath
       
   200         self.url      = url
       
   201         self.absUrl   = absUrl
       
   202         XMLTreeBuilder.__init__(self)
       
   203 
       
   204     def _start(self, tag, attrib_in):
       
   205         element = XMLTreeBuilder._start(self, tag, attrib_in)
       
   206         element.filePath = self.filePath
       
   207         element.url      = self.url
       
   208         element.absUrl   = self.absUrl
       
   209         element.startLineNumber = self._parser.ErrorLineNumber
       
   210         return element
       
   211         
       
   212     def _end(self, tag):
       
   213         element = XMLTreeBuilder._end(self, tag)
       
   214         element.endLineNumber = self._parser.ErrorLineNumber
       
   215         return element
       
   216         
       
   217