You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

704 lines
34 KiB

#
# minixsv, Release 0.9.0
# file: xsvalSimpleTypes.py
#
# class for validation of XML schema simple types
#
# history:
# 2004-09-09 rl created
# 2006-08-18 rl W3C testsuite passed for supported features
# 2007-05-24 rl Features for release 0.8 added, some bugs fixed
#
# Copyright (c) 2004-2007 by Roland Leuthe. All rights reserved.
#
# --------------------------------------------------------------------
# The minixsv XML schema validator is
#
# Copyright (c) 2004-2007 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 sys
import string
import re
import datetime
from decimal import Decimal
from ..genxmlif.xmlifUtils import removeWhitespaces, collapseString, normalizeString, NsNameTupleFactory
from ..minixsv import XSD_NAMESPACE
from xsvalUtils import substituteSpecialEscChars
###################################################
# Validator class for simple types
###################################################
class XsSimpleTypeVal:
def __init__ (self, parent):
self.parent = parent
self.xmlIf = parent.xmlIf
self.xsdNsURI = parent.xsdNsURI
self.xsdIdDict = parent.xsdIdDict
self.xsdIdRefDict = parent.xsdIdRefDict
def unlink (self):
self.parent = None
########################################
# validate given value against simpleType
#
def checkSimpleType (self, inputNode, attrName, typeName, attributeValue, returnDict, idCheck):
returnDict["adaptedAttrValue"] = attributeValue
returnDict["BaseTypes"].append(str(typeName))
if _suppBaseTypeDict.has_key(typeName):
try:
_suppBaseTypeDict[typeName] (inputNode, typeName, attributeValue, returnDict)
returnDict["primitiveType"] = typeName
except BaseTypeError, errstr:
raise SimpleTypeError("Value of %s (%s) %s" %(repr(attrName), repr(attributeValue), errstr))
elif self.parent.xsdTypeDict.has_key(typeName):
typedefNode = self.parent.xsdTypeDict[typeName]
if typedefNode.getNsName() == (XSD_NAMESPACE, "simpleType"):
self.checkSimpleTypeDef (inputNode, typedefNode, attrName, attributeValue, returnDict, idCheck)
elif (typedefNode.getNsName() == (XSD_NAMESPACE, "complexType") and
typedefNode.getFirstChild().getNsName() == (XSD_NAMESPACE, "simpleContent")):
self.checkSimpleTypeDef (inputNode, typedefNode.getFirstChild(), attrName, attributeValue, returnDict, idCheck)
elif typedefNode.getAttribute("mixed") == "true":
self.checkSimpleType (inputNode, attrName, (XSD_NAMESPACE, "string"), attributeValue, returnDict, idCheck)
elif typeName != (XSD_NAMESPACE, "anyType"):
raise SimpleTypeError("Attribute %s requires a simple type!" %repr(attrName))
if idCheck:
adaptedAttrValue = returnDict["adaptedAttrValue"]
if typeName == (XSD_NAMESPACE, "ID"):
if not self.xsdIdDict.has_key(adaptedAttrValue):
self.xsdIdDict[adaptedAttrValue] = inputNode
else:
raise SimpleTypeError("There are multiple occurences of ID value %s!" %repr(adaptedAttrValue))
if typeName == (XSD_NAMESPACE, "IDREF"):
self.xsdIdRefDict[adaptedAttrValue] = inputNode
else:
# TODO: Fehler im XSD-File => Check muss an anderer Stelle erfolgen
raise SimpleTypeError("%s uses unknown type %s!" %(repr(attrName), repr(typeName)))
########################################
# validate given value against simpleType node
#
def checkSimpleTypeDef (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
returnDict["adaptedAttrValue"] = attributeValue
restrictionElement = xsdElement.getFirstChildNS(self.xsdNsURI, "restriction")
extensionElement = xsdElement.getFirstChildNS(self.xsdNsURI, "extension")
listElement = xsdElement.getFirstChildNS(self.xsdNsURI, "list")
unionElement = xsdElement.getFirstChildNS(self.xsdNsURI, "union")
if restrictionElement != None:
self._checkRestrictionTag (inputNode, restrictionElement, attrName, attributeValue, returnDict, idCheck)
if extensionElement != None:
self._checkExtensionTag (inputNode, extensionElement, attrName, attributeValue, returnDict, idCheck)
elif listElement != None:
self._checkListTag (inputNode, listElement, attrName, attributeValue, returnDict, idCheck)
elif unionElement != None:
self._checkUnionTag (inputNode, unionElement, attrName, attributeValue, returnDict, idCheck)
########################################
# validate given value against base type
#
def checkBaseType (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
baseType = xsdElement.getQNameAttribute("base")
if baseType != NsNameTupleFactory(None):
self.checkSimpleType (inputNode, attrName, baseType, attributeValue, returnDict, idCheck)
else:
baseTypeNode = xsdElement.getFirstChildNS(self.xsdNsURI, "simpleType")
self.checkSimpleTypeDef (inputNode, baseTypeNode, attrName, attributeValue, returnDict, idCheck)
########################################
# validate given value against restriction node
#
def _checkRestrictionTag (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
savedAttrValue = attributeValue
# first check against base type
self.checkBaseType (inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck)
minExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "minExclusive")
minIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "minInclusive")
maxExcl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxExclusive")
maxIncl = xsdElement.getFirstChildNS(self.xsdNsURI, "maxInclusive")
if minExcl != None:
minExclReturnDict = {"BaseTypes":[], "primitiveType":None}
minExclValue = minExcl.getAttribute("value")
self.checkBaseType (inputNode, xsdElement, attrName, minExclValue, minExclReturnDict, idCheck=0)
if returnDict.has_key("orderedValue") and minExclReturnDict.has_key("orderedValue"):
if returnDict["orderedValue"] <= minExclReturnDict["orderedValue"]:
raise SimpleTypeError ("Value of %s (%s) is <= minExclusive (%s)" %(repr(attrName), repr(attributeValue), repr(minExclValue)))
elif minIncl != None:
minInclReturnDict = {"BaseTypes":[], "primitiveType":None}
minInclValue = minIncl.getAttribute("value")
self.checkBaseType (inputNode, xsdElement, attrName, minInclValue, minInclReturnDict, idCheck=0)
if returnDict.has_key("orderedValue") and minInclReturnDict.has_key("orderedValue"):
if returnDict["orderedValue"] < minInclReturnDict["orderedValue"]:
raise SimpleTypeError ("Value of %s (%s) is < minInclusive (%s)" %(repr(attrName), repr(attributeValue), repr(minInclValue)))
if maxExcl != None:
maxExclReturnDict = {"BaseTypes":[], "primitiveType":None}
maxExclValue = maxExcl.getAttribute("value")
self.checkBaseType (inputNode, xsdElement, attrName, maxExclValue, maxExclReturnDict, idCheck=0)
if returnDict.has_key("orderedValue") and maxExclReturnDict.has_key("orderedValue"):
if returnDict["orderedValue"] >= maxExclReturnDict["orderedValue"]:
raise SimpleTypeError ("Value of %s (%s) is >= maxExclusive (%s)" %(repr(attrName), repr(attributeValue), repr(maxExclValue)))
elif maxIncl != None:
maxInclReturnDict = {"BaseTypes":[], "primitiveType":None}
maxInclValue = maxIncl.getAttribute("value")
self.checkBaseType (inputNode, xsdElement, attrName, maxInclValue, maxInclReturnDict, idCheck=0)
if returnDict.has_key("orderedValue") and maxInclReturnDict.has_key("orderedValue"):
if returnDict["orderedValue"] > maxInclReturnDict["orderedValue"]:
raise SimpleTypeError ("Value of %s (%s) is > maxInclusive (%s)" %(repr(attrName), repr(attributeValue), repr(maxInclValue)))
totalDigitsNode = xsdElement.getFirstChildNS(self.xsdNsURI, "totalDigits")
if totalDigitsNode != None:
orderedValueStr = repr(returnDict["orderedValue"])
digits = re.findall("\d" ,orderedValueStr)
if digits[0] == "0" and len(digits) > 1:
digits = digits[1:]
totalDigitsValue = totalDigitsNode.getAttribute("value")
if totalDigitsNode.getAttribute("fixed") == "true":
if len(digits) != string.atoi(totalDigitsValue):
raise SimpleTypeError ("Total number of digits != %s for %s (%s)" %(repr(totalDigitsValue), repr(attrName), repr(attributeValue)))
else:
if len(digits) > string.atoi(totalDigitsValue):
raise SimpleTypeError ("Total number of digits > %s for %s (%s)" %(repr(totalDigitsValue), repr(attrName), repr(attributeValue)))
fractionDigitsNode = xsdElement.getFirstChildNS(self.xsdNsURI, "fractionDigits")
if fractionDigitsNode != None:
orderedValueStr = repr(returnDict["orderedValue"])
fractionDigitsValue = fractionDigitsNode.getAttribute("value")
result = re.search("(?P<intDigits>\d*)(?P<dot>\.)(?P<fracDigits>\d+)", orderedValueStr)
if result != None:
numberOfFracDigits = len (result.group('fracDigits'))
else:
numberOfFracDigits = 0
if fractionDigitsNode.getAttribute("fixed") == "true" and numberOfFracDigits != string.atoi(fractionDigitsValue):
raise SimpleTypeError ("Fraction number of digits != %s for %s (%s)" %(repr(fractionDigitsValue), repr(attrName), repr(attributeValue)))
elif numberOfFracDigits > string.atoi(fractionDigitsValue):
raise SimpleTypeError ("Fraction number of digits > %s for %s (%s)" %(repr(fractionDigitsValue), repr(attrName), repr(attributeValue)))
if returnDict.has_key("length"):
lengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "length")
if lengthNode != None:
length = string.atoi(lengthNode.getAttribute("value"))
if returnDict["length"] != length:
raise SimpleTypeError ("Length of %s (%s) must be %d!" %(repr(attrName), repr(attributeValue), length))
minLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "minLength")
if minLengthNode != None:
minLength = string.atoi(minLengthNode.getAttribute("value"))
if returnDict["length"] < minLength:
raise SimpleTypeError ("Length of %s (%s) must be >= %d!" %(repr(attrName), repr(attributeValue), minLength))
maxLengthNode = xsdElement.getFirstChildNS(self.xsdNsURI, "maxLength")
if maxLengthNode != None:
maxLength = string.atoi(maxLengthNode.getAttribute("value"))
if returnDict["length"] > maxLength:
raise SimpleTypeError ("Length of %s (%s) must be <= %d!" %(repr(attrName), repr(attributeValue), maxLength))
whiteSpace = xsdElement.getFirstChildNS(self.xsdNsURI, "whiteSpace")
if whiteSpace != None:
returnDict["wsAction"] = whiteSpace.getAttribute("value")
if returnDict["wsAction"] == "replace":
normalizedValue = normalizeString(attributeValue)
if normalizedValue != attributeValue:
returnDict["adaptedAttrValue"] = normalizedValue
elif returnDict["wsAction"] == "collapse":
collapsedValue = collapseString(attributeValue)
if collapsedValue != attributeValue:
returnDict["adaptedAttrValue"] = collapsedValue
enumerationElementList = xsdElement.getChildrenNS(self.xsdNsURI, "enumeration")
if enumerationElementList != []:
if returnDict.has_key("orderedValue"):
attributeValue = returnDict["orderedValue"]
elif returnDict.has_key("adaptedAttrValue"):
attributeValue = returnDict["adaptedAttrValue"]
for enumeration in enumerationElementList:
enumReturnDict = {"BaseTypes":[], "primitiveType":None}
enumValue = enumeration["value"]
self.checkBaseType (inputNode, xsdElement, attrName, enumValue, enumReturnDict, idCheck=0)
if enumReturnDict.has_key("orderedValue"):
enumValue = enumReturnDict["orderedValue"]
elif enumReturnDict.has_key("adaptedAttrValue"):
enumValue = enumReturnDict["adaptedAttrValue"]
if enumValue == attributeValue:
break
else:
raise SimpleTypeError ("Enumeration value %s not allowed!" %repr(attributeValue))
if returnDict.has_key("adaptedAttrValue"):
attributeValue = returnDict["adaptedAttrValue"]
patternMatch = 1
notMatchedPatternList = []
for patternNode in xsdElement.getChildrenNS(self.xsdNsURI, "pattern"):
rePattern = patternNode.getAttribute("value")
intRePattern = rePattern
try:
intRePattern = substituteSpecialEscChars (intRePattern)
except SyntaxError, errInst:
raise SimpleTypeError, str(errInst)
patternMatch = self._matchesPattern (intRePattern, attributeValue)
if patternMatch:
break
else:
notMatchedPatternList.append(rePattern)
if not patternMatch:
try:
pattern = " nor ".join(notMatchedPatternList)
except:
pattern = ""
raise SimpleTypeError ("Value of attribute %s (%s) does not match pattern %s!" %(repr(attrName), repr(attributeValue), repr(pattern)))
########################################
# checks if 'value' matches 'rePattern' completely
#
def _matchesPattern (self, intRePattern, attributeValue):
completePatternMatch = 0
try:
regexObj = re.match(intRePattern, attributeValue, re.U)
if regexObj and regexObj.end() == len(attributeValue):
completePatternMatch = 1
except Exception:
pass
return completePatternMatch
########################################
# validate given value against list node
#
def _checkListTag (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
if attributeValue != "":
itemType = xsdElement.getQNameAttribute ("itemType")
# substitute multiple whitespace characters by a single ' '
collapsedValue = collapseString(attributeValue)
returnDict["wsAction"] = "collapse"
returnDict["adaptedAttrValue"] = collapsedValue
# divide up attributeValue => store it into list
attributeList = string.split(collapsedValue, " ")
for attrValue in attributeList:
elementReturnDict = {"BaseTypes":[], "primitiveType":None}
if itemType != (None, None):
self.checkSimpleType (inputNode, attrName, itemType, attrValue, elementReturnDict, idCheck)
else:
itemTypeNode = xsdElement.getFirstChildNS(self.xsdNsURI, "simpleType")
self.checkSimpleTypeDef (inputNode, itemTypeNode, attrName, attrValue, elementReturnDict, idCheck)
returnDict["BaseTypes"].extend(elementReturnDict["BaseTypes"])
returnDict["length"] = len(attributeList)
else:
returnDict["length"] = 0
########################################
# validate given value against extension node
#
def _checkExtensionTag (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
# first check against base type
self.checkBaseType (inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck)
########################################
# validate given value against union node
#
def _checkUnionTag (self, inputNode, xsdElement, attrName, attributeValue, returnDict, idCheck):
memberTypes = xsdElement.getAttribute ("memberTypes")
if memberTypes != None:
# substitute multiple whitespace characters by a single ' '
# divide up attributeValue => store it into list
for memberType in string.split(collapseString(memberTypes), " "):
try:
self.checkSimpleType (inputNode, attrName, xsdElement.qName2NsName(memberType, useDefaultNs=1), attributeValue, returnDict, idCheck)
return
except SimpleTypeError, errstr:
pass
# memberTypes and additional type definitions is legal!
for childSimpleType in xsdElement.getChildrenNS(self.xsdNsURI, "simpleType"):
try:
self.checkSimpleTypeDef (inputNode, childSimpleType, attrName, attributeValue, returnDict, idCheck)
return
except SimpleTypeError, errstr:
pass
raise SimpleTypeError ("%s (%s) is no valid union member type!" %(repr(attrName), repr(attributeValue)))
###############################################################
# Base type check functions
###############################################################
reDecimal = re.compile("[+-]?[0-9]*\.?[0-9]+", re.U)
reInteger = re.compile("[+-]?[0-9]+", re.U)
reDouble = re.compile("([+-]?[0-9]*\.?[0-9]+([eE][+\-]?[0-9]+)?)|INF|-INF|NaN", re.U)
reHexBinary = re.compile("([a-fA-F0-9]{2})*", re.U)
reBase64Binary = re.compile("(?P<validBits>[a-zA-Z0-9+/]*)={0,3}", re.U)
reQName = re.compile(substituteSpecialEscChars("\i\c*"), re.U)
reDuration = re.compile("-?P(?P<years>\d+Y)?(?P<months>\d+M)?(?P<days>\d+D)?(T(?P<hours>\d+H)?(?P<minutes>\d+M)?((?P<seconds>\d+)(?P<fracsec>\.\d+)?S)?)?", re.U)
reDateTime = re.compile("(?P<date>\d{4}-\d{2}-\d{2})T(?P<time>\d{2}:\d{2}:\d{2}(\.\d+)?)(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reDate = re.compile("\d{4}-\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reTime = re.compile("(?P<time>\d{2}:\d{2}:\d{2})(?P<fracsec>\.\d+)?(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reYearMonth = re.compile("\d{4}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonthDay = re.compile("--\d{2}-\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reYear = re.compile("(?P<year>\d{1,4})(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reMonth = re.compile("--\d{2}(--)?(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
reDay = re.compile("---\d{2}(?P<offset>Z|[+-]\d{2}:\d{2})?", re.U)
def _checkAnySimpleType (inputNode, simpleType, attributeValue, returnDict):
# TODO: Nothing to check??
returnDict["length"] = len(attributeValue)
def _checkStringType (inputNode, simpleType, attributeValue, returnDict):
# TODO: all valid??
returnDict["length"] = len(attributeValue)
def _checkAnyUriType (inputNode, simpleType, attributeValue, returnDict):
# TODO: any checks??
if attributeValue[0:2] == '##':
raise BaseTypeError("is not a valid URI!")
returnDict["adaptedAttrValue"] = collapseString(attributeValue)
returnDict["wsAction"] = "collapse"
returnDict["length"] = len(attributeValue)
def _checkDecimalType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDecimal.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a decimal value!")
try:
value = Decimal(attributeValue)
returnDict["orderedValue"] = value.normalize()
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
except:
raise BaseTypeError("is not a decimal value!")
def _checkIntegerType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reInteger.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not an integer value!")
try:
returnDict["orderedValue"] = Decimal(attributeValue)
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
except:
raise BaseTypeError("is out of range for validation!")
def _checkFloatType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
if attributeValue not in ("INF", "-INF", "NaN"):
try:
value = float(attributeValue)
returnDict["orderedValue"] = value
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
except:
raise BaseTypeError("is not a float value!")
def _checkDoubleType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDouble.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a double value!")
try:
value = Decimal(attributeValue)
returnDict["orderedValue"] = value.normalize()
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
except:
raise BaseTypeError("is not a double value!")
def _checkHexBinaryType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = removeWhitespaces(attributeValue)
regexObj = reHexBinary.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a hexBinary value (each byte is represented by 2 characters)!")
returnDict["length"] = len(attributeValue) / 2
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkBase64BinaryType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reBase64Binary.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a base64Binary value (6 bits are represented by 1 character)!")
returnDict["length"] = (len(regexObj.group("validBits")) * 6) / 8
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkBooleanType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
if attributeValue not in ("true", "false", "1", "0"):
raise BaseTypeError("is not a boolean value!")
if attributeValue in ("true", "1"):
returnDict["orderedValue"] = "__BOOLEAN_TRUE__"
else:
returnDict["orderedValue"] = "__BOOLEAN_FALSE__"
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkQNameType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reQName.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a QName!")
try:
inputNode.getNamespace(attributeValue)
except LookupError:
raise BaseTypeError("is not a valid QName (namespace prefix unknown)!")
returnDict["length"] = len(attributeValue)
returnDict["orderedValue"] = inputNode.qName2NsName(attributeValue, useDefaultNs=1)
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkDurationType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDuration.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue) or attributeValue[-1] == "T" or attributeValue[-1] == "P":
raise BaseTypeError("is not a valid duration value!")
sign = ""
if attributeValue[0] == "-": sign = "-"
days = 0
seconds = 0
microseconds = 0
if regexObj.group("years") != None:
days = days + (int(sign + regexObj.group("years")[:-1]) * 365)
if regexObj.group("months") != None:
days = days + (int(sign + regexObj.group("months")[:-1]) * 30)
if regexObj.group("days") != None:
days = days + int(sign + regexObj.group("days")[:-1])
if regexObj.group("hours") != None:
seconds = seconds + int(sign + regexObj.group("hours")[:-1]) * 3600
if regexObj.group("minutes") != None:
seconds = seconds + (int(sign + regexObj.group("minutes")[:-1]) * 60)
if regexObj.group("seconds") != None:
seconds = seconds + int(sign + regexObj.group("seconds"))
if regexObj.group("fracsec") != None:
microseconds = int(Decimal(sign + regexObj.group("fracsec")) * 1000000)
try:
timeDeltaObj = datetime.timedelta(days=days, seconds=seconds, microseconds=microseconds)
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = timeDeltaObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkDateTimeType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDateTime.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a dateTime value!")
date = regexObj.group("date")
time = regexObj.group("time")
offset = regexObj.group("offset")
try:
if offset != None:
tz = TimezoneFixedOffset(offset)
else:
tz = None
dtObj = datetime.datetime(int(date[0:4]),int(date[5:7]),int(date[8:10]),
int(time[0:2]),int(time[3:5]),int(time[6:8]), 0, tz)
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = dtObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkDateType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDate.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a date value!")
try:
dateObj = datetime.date(int(attributeValue[0:4]),int(attributeValue[5:7]),int(attributeValue[8:10]))
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = dateObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkTimeType (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reTime.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a time value!")
time = regexObj.group("time")
fracsec = regexObj.group("fracsec")
offset = regexObj.group("offset")
try:
if offset != None:
tz = TimezoneFixedOffset(offset)
else:
tz = None
if fracsec != None:
fracSec = int(fracsec[1:])
else:
fracSec = 0
timeObj = datetime.time(int(time[0:2]),int(time[3:5]),int(time[6:8]), fracSec, tz)
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = timeObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkYearMonth (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reYearMonth.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a gYearMonth value!")
try:
dateObj = datetime.date(int(attributeValue[0:4]),int(attributeValue[5:7]),1)
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = dateObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkMonthDay (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reMonthDay.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a gMonthDay value!")
try:
dateObj = datetime.date(2004, int(attributeValue[2:4]),int(attributeValue[5:7]))
except ValueError, errstr:
raise BaseTypeError("is invalid (%s)!" %(errstr))
returnDict["orderedValue"] = dateObj
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkYear (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reYear.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue or regexObj.group("year") == None):
raise BaseTypeError("is not a gYear value (1)!")
try:
year = int(regexObj.group("year"))
if year < 1 or year > 9999:
raise BaseTypeError("is not a valid gYear value!")
except:
raise BaseTypeError("is not a gYear value!")
returnDict["orderedValue"] = year
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkMonth (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reMonth.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a gMonth value!")
month = int(attributeValue[2:4])
if month < 1 or month > 12:
raise BaseTypeError("is invalid (month must be in 1..12)!")
returnDict["orderedValue"] = month
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
def _checkDay (inputNode, simpleType, attributeValue, returnDict):
attributeValue = collapseString(attributeValue)
regexObj = reDay.match(attributeValue)
if not regexObj or regexObj.end() != len(attributeValue):
raise BaseTypeError("is not a gDay value!")
day = int(attributeValue[3:5])
if day < 1 or day > 31:
raise BaseTypeError("is invalid (day must be in 1..31)!")
returnDict["orderedValue"] = day
returnDict["adaptedAttrValue"] = attributeValue
returnDict["wsAction"] = "collapse"
########################################
# timezone class
#
class TimezoneFixedOffset(datetime.tzinfo):
def __init__(self, offset):
if offset == "Z":
self.__offset = datetime.timedelta(0)
else:
self.__offset = datetime.timedelta(hours=int(offset[0:3]),
minutes=int(offset[0] + offset[4:5]))
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return None
def dst(self, dt):
return datetime.timedelta(0)
########################################
# define own exception for XML schema validation errors
#
class SimpleTypeError (StandardError):
pass
class BaseTypeError (StandardError):
pass
########################################
# Base type dictionaries
#
_suppBaseTypeDict = {(XSD_NAMESPACE, "anySimpleType"): _checkAnySimpleType,
(XSD_NAMESPACE, "string"): _checkStringType,
(XSD_NAMESPACE, "anyURI"): _checkAnyUriType,
(XSD_NAMESPACE, "decimal"): _checkDecimalType,
(XSD_NAMESPACE, "integer"): _checkIntegerType,
(XSD_NAMESPACE, "float"): _checkFloatType,
(XSD_NAMESPACE, "double"): _checkDoubleType,
(XSD_NAMESPACE, "hexBinary"): _checkHexBinaryType,
(XSD_NAMESPACE, "base64Binary"): _checkBase64BinaryType,
(XSD_NAMESPACE, "boolean"): _checkBooleanType,
(XSD_NAMESPACE, "QName"): _checkQNameType,
(XSD_NAMESPACE, "NOTATION"): _checkQNameType,
(XSD_NAMESPACE, "duration"): _checkDurationType,
(XSD_NAMESPACE, "dateTime"): _checkDateTimeType,
(XSD_NAMESPACE, "date"): _checkDateType,
(XSD_NAMESPACE, "time"): _checkTimeType,
(XSD_NAMESPACE, "gYearMonth"): _checkYearMonth,
(XSD_NAMESPACE, "gMonthDay"): _checkMonthDay,
(XSD_NAMESPACE, "gYear"): _checkYear,
(XSD_NAMESPACE, "gMonth"): _checkMonth,
(XSD_NAMESPACE, "gDay"): _checkDay,
}