xmlifUtils.py
Go to the documentation of this file.
00001 #
00002 # genxmlif, Release 0.9.0
00003 # file: xmlifUtils.py
00004 #
00005 # utility module for genxmlif
00006 #
00007 # history:
00008 # 2005-04-25 rl   created
00009 # 2008-08-01 rl   encoding support added
00010 #
00011 # Copyright (c) 2005-2008 by Roland Leuthe.  All rights reserved.
00012 #
00013 # --------------------------------------------------------------------
00014 # The generic XML interface is
00015 #
00016 # Copyright (c) 2005-2008 by Roland Leuthe
00017 #
00018 # By obtaining, using, and/or copying this software and/or its
00019 # associated documentation, you agree that you have read, understood,
00020 # and will comply with the following terms and conditions:
00021 #
00022 # Permission to use, copy, modify, and distribute this software and
00023 # its associated documentation for any purpose and without fee is
00024 # hereby granted, provided that the above copyright notice appears in
00025 # all copies, and that both that copyright notice and this permission
00026 # notice appear in supporting documentation, and that the name of
00027 # the author not be used in advertising or publicity
00028 # pertaining to distribution of the software without specific, written
00029 # prior permission.
00030 #
00031 # THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
00032 # TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
00033 # ABILITY AND FITNESS.  IN NO EVENT SHALL THE AUTHOR
00034 # BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
00035 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
00036 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00037 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
00038 # OF THIS SOFTWARE.
00039 # --------------------------------------------------------------------
00040 
00041 import string
00042 import re
00043 import os
00044 import urllib
00045 import urlparse
00046 from types   import StringTypes, TupleType
00047 from xml.dom import EMPTY_PREFIX, EMPTY_NAMESPACE
00048 
00049 ######################################################################
00050 # DEFINITIONS
00051 ######################################################################
00052 
00053 ######################################################################
00054 # REGULAR EXPRESSION OBJECTS
00055 ######################################################################
00056 
00057 _reWhitespace  = re.compile('\s')
00058 _reWhitespaces = re.compile('\s+')
00059 
00060 _reSplitUrlApplication = re.compile (r"(file|http|ftp|gopher):(.+)") # "file:///d:\test.xml" => "file" + "///d:\test.xml"
00061 
00062 
00063 ######################################################################
00064 # FUNCTIONS
00065 ######################################################################
00066 
00067 
00068 ########################################
00069 # remove all whitespaces from a string
00070 #
00071 def removeWhitespaces (strValue):
00072     return _reWhitespaces.sub('', strValue)
00073 
00074 
00075 ########################################
00076 # substitute multiple whitespace characters by a single ' '
00077 #
00078 def collapseString (strValue, lstrip=1, rstrip=1):
00079     collStr = _reWhitespaces.sub(' ', strValue)
00080     if lstrip and rstrip:
00081         return collStr.strip()
00082     elif lstrip:
00083         return collStr.lstrip()
00084     elif rstrip:
00085         return collStr.rstrip()
00086     else:
00087         return collStr
00088         
00089 
00090 
00091 ########################################
00092 # substitute each whitespace characters by a single ' '
00093 #
00094 def normalizeString (strValue):
00095     return _reWhitespace.sub(' ', strValue)
00096 
00097 
00098 ########################################
00099 # process whitespace action
00100 #
00101 def processWhitespaceAction (strValue, wsAction, lstrip=1, rstrip=1):
00102     if wsAction == "collapse":
00103         return collapseString(strValue, lstrip, rstrip)
00104     elif wsAction == "replace":
00105         return normalizeString(strValue)
00106     else:
00107         return strValue
00108     
00109 
00110 ##########################################################
00111 #  convert input parameter 'fileOrUrl' into a valid URL
00112 
00113 def convertToUrl (fileOrUrl):
00114     matchObject = _reSplitUrlApplication.match(fileOrUrl)
00115     if matchObject:
00116         # given fileOrUrl is an absolute URL
00117         if matchObject.group(1) == 'file':
00118             path = re.sub(':', '|', matchObject.group(2)) # replace ':' by '|' in the path string
00119             url = "file:" + path
00120         else:
00121             url = fileOrUrl
00122     elif not os.path.isfile(fileOrUrl):
00123         # given fileOrUrl is treated as a relative URL
00124         url = fileOrUrl
00125     else:
00126         # local filename
00127 #        url = "file:" + urllib.pathname2url (fileOrUrl)
00128         url = urllib.pathname2url (fileOrUrl)
00129 
00130     return url
00131 
00132 
00133 ##########################################################
00134 #  convert input parameter 'fileOrUrl' into a valid absolute URL
00135 
00136 def convertToAbsUrl (fileOrUrl, baseUrl):
00137     if fileOrUrl == "" and baseUrl != "":
00138         absUrl = "file:" + urllib.pathname2url (os.path.join(os.getcwd(), baseUrl, "__NO_FILE__"))
00139     elif os.path.isfile(fileOrUrl):
00140         absUrl = "file:" + urllib.pathname2url (os.path.join(os.getcwd(), fileOrUrl))
00141     else:
00142         matchObject = _reSplitUrlApplication.match(fileOrUrl)
00143         if matchObject:
00144             # given fileOrUrl is an absolute URL
00145             if matchObject.group(1) == 'file':
00146                 path = re.sub(':', '|', matchObject.group(2)) # replace ':' by '|' in the path string
00147                 absUrl = "file:" + path
00148             else:
00149                 absUrl = fileOrUrl
00150         else:
00151             # given fileOrUrl is treated as a relative URL
00152             if baseUrl != "":
00153                 absUrl = urlparse.urljoin (baseUrl, fileOrUrl)
00154             else:
00155                 absUrl = fileOrUrl
00156 #                raise IOError, "File %s not found!" %(fileOrUrl)
00157     return absUrl
00158 
00159 
00160 ##########################################################
00161 #  normalize filter
00162 def normalizeFilter (filterVar):
00163     if filterVar == None or filterVar == '*':
00164         filterVar = ("*",)
00165     elif not isinstance(filterVar, TupleType):
00166         filterVar = (filterVar,)
00167     return filterVar
00168 
00169 
00170 ######################################################################
00171 # Namespace handling
00172 ######################################################################
00173 
00174 def nsNameToQName (nsLocalName, curNs):
00175     """Convert a tuple '(namespace, localName)' to a string 'prefix:localName'
00176     
00177     Input parameter:
00178         nsLocalName:   tuple '(namespace, localName)' to be converted
00179         curNs:         list of current namespaces
00180     Returns the corresponding string 'prefix:localName' for 'nsLocalName'.
00181     """
00182     ns = nsLocalName[0]
00183     for prefix, namespace in curNs:
00184         if ns == namespace:
00185             if prefix != None:
00186                 return "%s:%s" %(prefix, nsLocalName[1])
00187             else:
00188                 return "%s" %nsLocalName[1]
00189     else:
00190         if ns == None:
00191             return nsLocalName[1]
00192         else:
00193             raise LookupError, "Prefix for namespaceURI '%s' not found!" % (ns)
00194 
00195 
00196 def splitQName (qName):
00197     """Split the given 'qName' into prefix/namespace and local name.
00198 
00199     Input parameter:
00200         'qName':  contains a string 'prefix:localName' or '{namespace}localName'
00201     Returns a tuple (prefixOrNamespace, localName)
00202     """
00203     namespaceEndIndex = string.find (qName, '}')
00204     if namespaceEndIndex != -1:
00205         prefix     = qName[1:namespaceEndIndex]
00206         localName  = qName[namespaceEndIndex+1:]
00207     else:
00208         namespaceEndIndex = string.find (qName, ':')
00209         if namespaceEndIndex != -1:
00210             prefix     = qName[:namespaceEndIndex]
00211             localName  = qName[namespaceEndIndex+1:]
00212         else:
00213             prefix     = None
00214             localName  = qName
00215     return prefix, localName
00216 
00217 
00218 def toClarkQName (tupleOrLocalName):
00219     """converts a tuple (namespace, localName) into clark notation {namespace}localName
00220        qNames without namespace remain unchanged
00221 
00222     Input parameter:
00223         'tupleOrLocalName':  tuple '(namespace, localName)' to be converted
00224     Returns a string {namespace}localName
00225     """
00226     if isinstance(tupleOrLocalName, TupleType):
00227         if tupleOrLocalName[0] != EMPTY_NAMESPACE:
00228             return "{%s}%s" %(tupleOrLocalName[0], tupleOrLocalName[1])
00229         else:
00230             return tupleOrLocalName[1]
00231     else:
00232         return tupleOrLocalName
00233     
00234     
00235 def splitClarkQName (qName):
00236     """converts clark notation {namespace}localName into a tuple (namespace, localName)
00237 
00238     Input parameter:
00239         'qName':  {namespace}localName to be converted
00240     Returns prefix and localName as separate strings
00241     """
00242     namespaceEndIndex = string.find (qName, '}')
00243     if namespaceEndIndex != -1:
00244         prefix     = qName[1:namespaceEndIndex]
00245         localName  = qName[namespaceEndIndex+1:]
00246     else:
00247         prefix     = None
00248         localName  = qName
00249     return prefix, localName
00250     
00251     
00252 ##################################################################
00253 # XML serialization of text
00254 # the following functions assume an ascii-compatible encoding
00255 # (or "utf-16")
00256 
00257 _escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"'))
00258 
00259 _escapeDict = {
00260     "&": "&amp;",
00261     "<": "&lt;",
00262     ">": "&gt;",
00263     '"': "&quot;",
00264 }
00265 
00266 
00267 def _raiseSerializationError(text):
00268     raise TypeError("cannot serialize %r (type %s)" % (text, type(text).__name__))
00269 
00270 
00271 def _encode(text, encoding):
00272     try:
00273         return text.encode(encoding)
00274     except AttributeError:
00275         return text # assume the string uses the right encoding
00276 
00277 
00278 def _encodeEntity(text, pattern=_escape):
00279     # map reserved and non-ascii characters to numerical entities
00280     def escapeEntities(m, map=_escapeDict):
00281         out = []
00282         append = out.append
00283         for char in m.group():
00284             text = map.get(char)
00285             if text is None:
00286                 text = "&#%d;" % ord(char)
00287             append(text)
00288         return string.join(out, "")
00289     try:
00290         return _encode(pattern.sub(escapeEntities, text), "ascii")
00291     except TypeError:
00292         _raise_serialization_error(text)
00293 
00294 
00295 def escapeCdata(text, encoding=None, replace=string.replace):
00296     # escape character data
00297     try:
00298         if encoding:
00299             try:
00300                 text = _encode(text, encoding)
00301             except UnicodeError:
00302                 return _encodeEntity(text)
00303         text = replace(text, "&", "&amp;")
00304         text = replace(text, "<", "&lt;")
00305         text = replace(text, ">", "&gt;")
00306         return text
00307     except (TypeError, AttributeError):
00308         _raiseSerializationError(text)
00309 
00310 
00311 def escapeAttribute(text, encoding=None, replace=string.replace):
00312     # escape attribute value
00313     try:
00314         if encoding:
00315             try:
00316                 text = _encode(text, encoding)
00317             except UnicodeError:
00318                 return _encodeEntity(text)
00319         text = replace(text, "&", "&amp;")
00320         text = replace(text, "'", "&apos;") # FIXME: overkill
00321         text = replace(text, "\"", "&quot;")
00322         text = replace(text, "<", "&lt;")
00323         text = replace(text, ">", "&gt;")
00324         return text
00325     except (TypeError, AttributeError):
00326         _raiseSerializationError(text)
00327 
00328 
00329 ######################################################################
00330 # CLASSES
00331 ######################################################################
00332 
00333 ######################################################################
00334 # class containing a tuple of namespace prefix and localName
00335 #
00336 class QNameTuple(tuple):
00337     def __str__(self):
00338         if self[0] != EMPTY_PREFIX:
00339             return "%s:%s" %(self[0],self[1])
00340         else:
00341             return self[1]
00342     
00343 
00344 def QNameTupleFactory(initValue):
00345     if isinstance(initValue, StringTypes):
00346         separatorIndex = string.find (initValue, ':')
00347         if separatorIndex != -1:
00348             initValue = (initValue[:separatorIndex], initValue[separatorIndex+1:])
00349         else:
00350            initValue = (EMPTY_PREFIX, initValue)
00351     return QNameTuple(initValue)
00352 
00353 
00354 ######################################################################
00355 # class containing a tuple of namespace and localName
00356 #
00357 class NsNameTuple(tuple):
00358     def __str__(self):
00359         if self[0] != EMPTY_NAMESPACE:
00360             return "{%s}%s" %(self[0],self[1])
00361         elif self[1] != None:
00362             return self[1]
00363         else:
00364             return "None"
00365 
00366 
00367 def NsNameTupleFactory(initValue):
00368     if isinstance(initValue, StringTypes):
00369         initValue = splitClarkQName(initValue)
00370     elif initValue == None:
00371         initValue = (EMPTY_NAMESPACE, initValue)
00372     return NsNameTuple(initValue)
00373 
00374 


mavlink
Author(s): Lorenz Meier
autogenerated on Sun May 22 2016 04:05:43