Ejemplo n.º 1
0
def linkbase_link_roles(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    arcroleURI = stringArg(xc, args, 0, "xs:string")
    relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI)
    if relationshipSet:
        return [anyURI(linkrole) for linkrole in relationshipSet.linkRoleUris]
    return ()
Ejemplo n.º 2
0
def linkbase_link_roles(xc, p, args):
    if len(args) != 1: raise XPathContext.FunctionNumArgs()
    arcroleURI = stringArg(xc, args, 0, "xs:string")
    relationshipSet = xc.modelXbrl.relationshipSet(arcroleURI)
    if relationshipSet:
        return [anyURI(linkrole) for linkrole in relationshipSet.linkRoleUris]
    return ()
Ejemplo n.º 3
0
 def atomize(self, p, x):
     # sequence
     if isinstance(x, SEQUENCE_TYPES):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, _RANGE):
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelFact):
         if x.isTuple:
             raise XPathException(
                 p, 'err:FOTY0012',
                 _('Atomizing tuple {0} that does not have a typed value').
                 format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value  # resolves default value
         e = x
     elif isinstance(
             x, ModelAttribute
     ):  # ModelAttribute is a tuple (below), check this first!
         return x.xValue
     else:
         if isinstance(x, ModelObject):
             e = x
         if e is not None:
             if getattr(e, "xValid", 0) == VALID_NO_CONTENT:
                 raise XPathException(
                     p, 'err:FOTY0012',
                     _('Atomizing element {0} that does not have a typed value'
                       ).format(x))
             if e.get("{http://www.w3.org/2001/XMLSchema-instance}nil"
                      ) == "true":
                 return []
             try:
                 if e.xValid >= VALID:
                     return e.xValue
             except AttributeError:
                 pass
             modelXbrl = x.modelXbrl
             modelConcept = modelXbrl.qnameConcepts.get(qname(x))
             if modelConcept is not None:
                 baseXsdType = modelConcept.baseXsdType
             v = x.stringValue
     if baseXsdType in ("float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to a {1} does not have a proper value').
                 format(x, baseXsdType))
     elif baseXsdType == "decimal":
         try:
             x = Decimal(v)
         except InvalidOperation:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to decimal does not have a proper value'))
     elif baseXsdType in ("integer", "nonPositiveInteger",
                          "negativeInteger", "nonNegativeInteger",
                          "positiveInteger", "long", "unsignedLong", "int",
                          "unsignedInt", "short", "unsignedShort", "byte",
                          "unsignedByte"):
         try:
             x = _INT(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to an integer does not have a proper value'
                   ).format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e is not None:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString", "token", "language",
                          "NMTOKEN", "Name", "NCName", "ID", "IDREF",
                          "ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType in GREGORIAN_TYPES and isinstance(v, GREGORIAN_TYPES):
         x = v
     elif baseXsdType == "noContent":
         x = None  # can't be atomized
     elif baseXsdType:
         x = str(v)
     return x
Ejemplo n.º 4
0
def validateValue(modelXbrl, elt, attrTag, baseXsdType, value, isNillable=False, isNil=False, facets=None):
    if baseXsdType:
        try:
            '''
            if (len(value) == 0 and attrTag is None and not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            '''
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace and baseXsdType != "string")
            isList = baseXsdType in {"IDREFS", "ENTITIES", "NMTOKENS"}
            if isList:
                baseXsdType = baseXsdType[:-1] # remove plural
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {"preserve":(False,False), "replace":(True,False), "collapse":(False,True)}[facets["whiteSpace"]]
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value.strip())
            if baseXsdType == "noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError("value content not permitted")
                # note that sValue and xValue are not innerText but only text elements on specific element (or attribute)
                xValue = sValue = None
                xValid = VALID_NO_CONTENT # notify others that element may contain subelements (for stringValue needs)
            elif not value and isNil and isNillable: # rest of types get None if nil/empty value
                xValue = sValue = None
            else:
                if pattern is not None:
                    if ((isList and any(pattern.match(v) is None for v in value.split())) or
                        (not isList and pattern.match(value) is None)):
                        raise ValueError("pattern facet " + facets["pattern"].pattern if facets and "pattern" in facets else "pattern mismatch")
                if facets:
                    if "enumeration" in facets and value not in facets["enumeration"]:
                        raise ValueError("{0} is not in {1}".format(value, facets["enumeration"]))
                    if "length" in facets and len(value) != facets["length"]:
                        raise ValueError("length {0}, expected {1}".format(len(value), facets["length"]))
                    if "minLength" in facets and len(value) < facets["minLength"]:
                        raise ValueError("length {0}, minLength {1}".format(len(value), facets["minLength"]))
                    if "maxLength" in facets and len(value) > facets["maxLength"]:
                        raise ValueError("length {0}, maxLength {1}".format(len(value), facets["maxLength"]))
                if baseXsdType in {"string", "normalizedString", "language", "token", "NMTOKEN","Name","NCName","IDREF","ENTITY"}:
                    xValue = sValue = value
                elif baseXsdType == "ID":
                    xValue = sValue = value
                    xValid = VALID_ID
                elif baseXsdType == "anyURI":
                    if value:  # allow empty strings to be valid anyURIs
                        if UrlUtil.relativeUrlPattern.match(value) is None:
                            raise ValueError("IETF RFC 2396 4.3 syntax")
                    # encode PSVI xValue similarly to Xerces and other implementations
                    xValue = anyURI(UrlUtil.anyUriQuoteForPSVI(value))
                    sValue = value
                elif baseXsdType in ("decimal", "float", "double"):
                    if baseXsdType == "decimal":
                        if decimalPattern.match(value) is None:
                            raise ValueError("lexical pattern mismatch")
                        xValue = Decimal(value)
                        sValue = float(value) # s-value uses Number (float) representation
                    else:
                        if floatPattern.match(value) is None:
                            raise ValueError("lexical pattern mismatch")
                        xValue = sValue = float(value)
                    if facets:
                        if "totalDigits" in facets and len(value.replace(".","")) > facets["totalDigits"]:
                            raise ValueError("totalDigits facet {0}".format(facets["totalDigits"]))
                        if "fractionDigits" in facets and ( '.' in value and
                            len(value[value.index('.') + 1:]) > facets["fractionDigits"]):
                            raise ValueError("fraction digits facet {0}".format(facets["fractionDigits"]))
                        if "maxInclusive" in facets and xValue > facets["maxInclusive"]:
                            raise ValueError(" > maxInclusive {0}".format(facets["maxInclusive"]))
                        if "maxExclusive" in facets and xValue >= facets["maxExclusive"]:
                            raise ValueError(" >= maxInclusive {0}".format(facets["maxExclusive"]))
                        if "minInclusive" in facets and xValue < facets["minInclusive"]:
                            raise ValueError(" < minInclusive {0}".format(facets["minInclusive"]))
                        if "minExclusive" in facets and xValue <= facets["minExclusive"]:
                            raise ValueError(" <= minExclusive {0}".format(facets["minExclusive"]))
                elif baseXsdType in {"integer",
                                     "nonPositiveInteger","negativeInteger","nonNegativeInteger","positiveInteger",
                                     "long","unsignedLong",
                                     "int","unsignedInt",
                                     "short","unsignedShort",
                                     "byte","unsignedByte"}:
                    xValue = sValue = _INT(value)
                    if ((baseXsdType in {"nonNegativeInteger","unsignedLong","unsignedInt"} 
                         and xValue < 0) or
                        (baseXsdType == "nonPositiveInteger" and xValue > 0) or
                        (baseXsdType == "positiveInteger" and xValue <= 0) or
                        (baseXsdType == "byte" and not -128 <= xValue < 127) or
                        (baseXsdType == "unsignedByte" and not 0 <= xValue < 255) or
                        (baseXsdType == "short" and not -32768 <= xValue < 32767) or
                        (baseXsdType == "unsignedShort" and not 0 <= xValue < 65535) or
                        (baseXsdType == "positiveInteger" and xValue <= 0)):
                        raise ValueError("{0} is not {1}".format(value, baseXsdType))
                    if facets:
                        if "totalDigits" in facets and len(value.replace(".","")) > facets["totalDigits"]:
                            raise ValueError("totalDigits facet {0}".format(facets["totalDigits"]))
                        if "fractionDigits" in facets and ( '.' in value and
                            len(value[value.index('.') + 1:]) > facets["fractionDigits"]):
                            raise ValueError("fraction digits facet {0}".format(facets["fractionDigits"]))
                        if "maxInclusive" in facets and xValue > facets["maxInclusive"]:
                            raise ValueError(" > maxInclusive {0}".format(facets["maxInclusive"]))
                        if "maxExclusive" in facets and xValue >= facets["maxExclusive"]:
                            raise ValueError(" >= maxInclusive {0}".format(facets["maxExclusive"]))
                        if "minInclusive" in facets and xValue < facets["minInclusive"]:
                            raise ValueError(" < minInclusive {0}".format(facets["minInclusive"]))
                        if "minExclusive" in facets and xValue <= facets["minExclusive"]:
                            raise ValueError(" <= minExclusive {0}".format(facets["minExclusive"]))
                elif baseXsdType == "boolean":
                    if value in ("true", "1"):  
                        xValue = sValue = True
                    elif value in ("false", "0"): 
                        xValue = sValue = False
                    else: raise ValueError
                elif baseXsdType == "QName":
                    xValue = qnameEltPfxName(elt, value, prefixException=ValueError)
                    #xValue = qname(elt, value, castException=ValueError, prefixException=ValueError)
                    sValue = value
                    ''' not sure here, how are explicitDimensions validated, but bad units not?
                    if xValue.namespaceURI in modelXbrl.namespaceDocs:
                        if (xValue not in modelXbrl.qnameConcepts and 
                            xValue not in modelXbrl.qnameTypes and
                            xValue not in modelXbrl.qnameAttributes and
                            xValue not in modelXbrl.qnameAttributeGroups):
                            raise ValueError("qname not defined " + str(xValue))
                    '''
                elif baseXsdType in ("XBRLI_DECIMALSUNION", "XBRLI_PRECISIONUNION"):
                    xValue = sValue = value if value == "INF" else _INT(value)
                elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                    xValue = sValue = _INT(value)
                    if xValue == 0:
                        raise ValueError("invalid value")
                elif baseXsdType == "XBRLI_DATEUNION":
                    xValue = dateTime(value, type=DATEUNION, castException=ValueError)
                    sValue = value
                elif baseXsdType == "dateTime":
                    xValue = dateTime(value, type=DATETIME, castException=ValueError)
                    sValue = value
                elif baseXsdType == "date":
                    xValue = dateTime(value, type=DATE, castException=ValueError)
                    sValue = value
                elif baseXsdType == "regex-pattern":
                    # for facet compiling
                    try:
                        sValue = value
                        if value in xmlSchemaPatterns:
                            xValue = xmlSchemaPatterns[value]
                        else:
                            if r"\i" in value or r"\c" in value:
                                value = value.replace(r"\i", iNameChar).replace(r"\c", cNameChar)
                            xValue = re_compile(value + "$") # must match whole string
                    except Exception as err:
                        raise ValueError(err)
                elif baseXsdType == "fraction":
                    sValue = value
                    xValue = Fraction("/".join(elt.fractionValue))
                else:
                    if baseXsdType in lexicalPatterns:
                        match = lexicalPatterns[baseXsdType].match(value)
                        if match is None:
                            raise ValueError("lexical pattern mismatch")
                        if baseXsdType == "gMonthDay":
                            month, day, zSign, zHrMin, zHr, zMin = match.groups()
                            if int(day) > {2:29, 4:30, 6:30, 9:30, 11:30, 1:31, 3:31, 5:31, 7:31, 8:31, 10:31, 12:31}[int(month)]:
                                raise ValueError("invalid day {0} for month {1}".format(day, month))
                            xValue = gMonthDay(month, day)
                        elif baseXsdType == "gYearMonth":
                            year, month, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gYearMonth(year, month)
                        elif baseXsdType == "gYear":
                            year, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gYear(year)
                        elif baseXsdType == "gMonth":
                            month, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gMonth(month)
                        elif baseXsdType == "gDay":
                            day, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gDay(day)
                        else:
                            xValue = value
                    else: # no lexical pattern, forget compiling value
                        xValue = value
                    sValue = value
        except (ValueError, InvalidOperation) as err:
            if ModelInlineValueObject is not None and isinstance(elt, ModelInlineValueObject):
                errElt = "{0} fact {1}".format(elt.elementQname, elt.qname)
            else:
                errElt = elt.elementQname
            if attrTag:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"),
                    modelObject=elt,
                    element=errElt,
                    attribute=XmlUtil.clarkNotationToPrefixedName(elt,attrTag,isAttribute=True),
                    typeName=baseXsdType,
                    value=value if len(value) < 31 else value[:30] + '...',
                    error=err)
            else:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s, %(error)s"),
                    modelObject=elt,
                    element=errElt,
                    typeName=baseXsdType,
                    value=value if len(value) < 31 else value[:30] + '...',
                    error=err)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        try:  # dynamically allocate attributes (otherwise given shared empty set)
            xAttributes = elt.xAttributes
        except AttributeError:
            elt.xAttributes = xAttributes = {}
        xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue, sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 5
0
def validateValue(modelXbrl, elt, attrTag, baseXsdType, value, isNillable=False, facets=None):
    if baseXsdType:
        try:
            if (len(value) == 0 and
                not attrTag is None and 
                not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace and baseXsdType != "string")
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {"preserve":(False,False), "replace":(True,False), "collapse":(False,True)}
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value.strip())
            if pattern is not None and pattern.match(value) is None:
                    raise ValueError("pattern facet " + facets["pattern"].pattern if facets and "pattern" in facets else "pattern mismatch")
            if facets:
                if "enumeration" in facets and value not in facets["enumeration"]:
                    raise ValueError("is not in {1}".format(value, facets["enumeration"]))
                if "length" in facets and len(value) != facets["length"]:
                    raise ValueError("length facet")
                if "minLength" in facets and len(value) < facets["minLength"]:
                    raise ValueError("minLength facet")
                if "maxLength" in facets and len(value) > facets["maxLength"]:
                    raise ValueError("maxLength facet")
            if baseXsdType == "noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError("value content not permitted")
                xValue = sValue = None
            elif baseXsdType in {"string", "normalizedString", "language", "token", "NMTOKEN","Name","NCName","IDREF","ENTITY"}:
                xValue = sValue = value
            elif baseXsdType == "ID":
                xValue = sValue = value
                xValid = VALID_ID
            elif baseXsdType == "anyURI":
                xValue = anyURI(value)
                sValue = value
                if xValue and not UrlUtil.isValid(xValue):  # allow empty strings to be valid anyURIs
                    raise ValueError("invalid anyURI value")
            elif not value: # rest of types get None if nil/empty value
                xValue = sValue = None
            elif baseXsdType in ("decimal", "float", "double"):
                xValue = sValue = float(value)
                if facets:
                    if "totalDigits" in facets and len(value.replace(".","")) != facets["totalDigits"]:
                        raise ValueError("total digits facet")
                    if "fractionDigits" in facets and ( '.' not in value or
                        len(value[value.index('.') + 1:]) != facets["fractionDigits"]):
                        raise ValueError("fraction digits facet")
            elif baseXsdType in ("integer",):
                xValue = sValue = int(value)
            elif baseXsdType == "boolean":
                if value in ("true", "1"):  
                    xValue = sValue = True
                elif value in ("false", "0"): 
                    xValue = sValue = False
                else: raise ValueError
            elif baseXsdType == "QName":
                xValue = qname(elt, value, castException=ValueError)
                sValue = value
                ''' not sure here, how are explicitDimensions validated, but bad units not?
                if xValue.namespaceURI in modelXbrl.namespaceDocs:
                    if (xValue not in modelXbrl.qnameConcepts and 
                        xValue not in modelXbrl.qnameTypes and
                        xValue not in modelXbrl.qnameAttributes and
                        xValue not in modelXbrl.qnameAttributeGroups):
                        raise ValueError("qname not defined " + str(xValue))
                '''
            elif baseXsdType in ("XBRLI_DECIMALSUNION", "XBRLI_PRECISIONUNION"):
                xValue = sValue = value if value == "INF" else int(value)
            elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                xValue = sValue = int(value)
                if xValue == 0:
                    raise ValueError("invalid value")
            elif baseXsdType == "XBRLI_DATEUNION":
                xValue = dateTime(value, type=DATEUNION, castException=ValueError)
                sValue = value
            elif baseXsdType == "dateTime":
                xValue = dateTime(value, type=DATETIME, castException=ValueError)
                sValue = value
            elif baseXsdType == "date":
                xValue = dateTime(value, type=DATE, castException=ValueError)
                sValue = value
            elif baseXsdType == "regex-pattern":
                # for facet compiling
                try:
                    xValue = re.compile(value + "$") # must match whole string
                    sValue = value
                except Exception as err:
                    raise ValueError(err)
            else:
                xValue = value
                sValue = value
        except ValueError as err:
            if attrTag:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"),
                    modelObject=elt,
                    element=elt.elementQname,
                    attribute=XmlUtil.clarkNotationToPrefixedName(elt,attrTag,isAttribute=True),
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            else:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s"),
                    modelObject=elt,
                    element=elt.elementQname,
                    typeName=baseXsdType,
                    value=value)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        elt.xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue, sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 6
0
def fact_identifier_scheme(xc, p, args):
    scheme = item_context_element(xc, args, "identifier").get("scheme")
    if scheme is None:
        return None
    return anyURI(scheme)
Ejemplo n.º 7
0
def identifier_scheme(xc, p, args):
    scheme = parent_child(args, "identifier", "@scheme")
    if scheme is None:
        return None
    return anyURI(scheme)
Ejemplo n.º 8
0
def validateValue(modelXbrl, elt, attrTag, baseXsdType, value, isNillable=False, isNil=False, facets=None):
    if baseXsdType:
        try:
            u'''
            if (len(value) == 0 and attrTag is None and not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            '''
            xValid = VALID
            whitespaceReplace = (baseXsdType == u"normalizedString")
            whitespaceCollapse = (not whitespaceReplace and baseXsdType != u"string")
            isList = baseXsdType in set([u"IDREFS", u"ENTITIES", u"NMTOKENS"])
            if isList:
                baseXsdType = baseXsdType[:-1] # remove plural
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if u"pattern" in facets:
                    pattern = facets[u"pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if u"whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {u"preserve":(False,False), u"replace":(True,False), u"collapse":(False,True)}[facets[u"whiteSpace"]]
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(u' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(u' ', value.strip())
            if baseXsdType == u"noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError(u"value content not permitted")
                # note that sValue and xValue are not innerText but only text elements on specific element (or attribute)
                xValue = sValue = None
                xValid = VALID_NO_CONTENT # notify others that element may contain subelements (for stringValue needs)
            elif not value and isNil and isNillable: # rest of types get None if nil/empty value
                xValue = sValue = None
            else:
                if pattern is not None:
                    if ((isList and any(pattern.match(v) is None for v in value.split())) or
                        (not isList and pattern.match(value) is None)):
                        raise ValueError(u"pattern facet " + facets[u"pattern"].pattern if facets and u"pattern" in facets else u"pattern mismatch")
                if facets:
                    if u"enumeration" in facets and value not in facets[u"enumeration"]:
                        raise ValueError(u"{0} is not in {1}".format(value, facets[u"enumeration"]))
                    if u"length" in facets and len(value) != facets[u"length"]:
                        raise ValueError(u"length {0}, expected {1}".format(len(value), facets[u"length"]))
                    if u"minLength" in facets and len(value) < facets[u"minLength"]:
                        raise ValueError(u"length {0}, minLength {1}".format(len(value), facets[u"minLength"]))
                    if u"maxLength" in facets and len(value) > facets[u"maxLength"]:
                        raise ValueError(u"length {0}, maxLength {1}".format(len(value), facets[u"maxLength"]))
                if baseXsdType in set([u"string", u"normalizedString", u"language", u"token", u"NMTOKEN",u"Name",u"NCName",u"IDREF",u"ENTITY"]):
                    xValue = sValue = value
                elif baseXsdType == u"ID":
                    xValue = sValue = value
                    xValid = VALID_ID
                elif baseXsdType == u"anyURI":
                    if value:  # allow empty strings to be valid anyURIs
                        if UrlUtil.relativeUrlPattern.match(value) is None:
                            raise ValueError(u"IETF RFC 2396 4.3 syntax")
                    # encode PSVI xValue similarly to Xerces and other implementations
                    xValue = anyURI(UrlUtil.anyUriQuoteForPSVI(value))
                    sValue = value
                elif baseXsdType in (u"decimal", u"float", u"double"):
                    if baseXsdType == u"decimal":
                        if decimalPattern.match(value) is None:
                            raise ValueError(u"lexical pattern mismatch")
                        xValue = Decimal(value)
                        sValue = float(value) # s-value uses Number (float) representation
                    else:
                        if floatPattern.match(value) is None:
                            raise ValueError(u"lexical pattern mismatch")
                        xValue = sValue = float(value)
                    if facets:
                        if u"totalDigits" in facets and len(value.replace(u".",u"")) > facets[u"totalDigits"]:
                            raise ValueError(u"totalDigits facet {0}".format(facets[u"totalDigits"]))
                        if u"fractionDigits" in facets and ( u'.' in value and
                            len(value[value.index(u'.') + 1:]) > facets[u"fractionDigits"]):
                            raise ValueError(u"fraction digits facet {0}".format(facets[u"fractionDigits"]))
                        if u"maxInclusive" in facets and xValue > facets[u"maxInclusive"]:
                            raise ValueError(u" > maxInclusive {0}".format(facets[u"maxInclusive"]))
                        if u"maxExclusive" in facets and xValue >= facets[u"maxExclusive"]:
                            raise ValueError(u" >= maxInclusive {0}".format(facets[u"maxExclusive"]))
                        if u"minInclusive" in facets and xValue < facets[u"minInclusive"]:
                            raise ValueError(u" < minInclusive {0}".format(facets[u"minInclusive"]))
                        if u"minExclusive" in facets and xValue <= facets[u"minExclusive"]:
                            raise ValueError(u" <= minExclusive {0}".format(facets[u"minExclusive"]))
                elif baseXsdType in set([u"integer",
                                     u"nonPositiveInteger",u"negativeInteger",u"nonNegativeInteger",u"positiveInteger",
                                     u"long",u"unsignedLong",
                                     u"int",u"unsignedInt",
                                     u"short",u"unsignedShort",
                                     u"byte",u"unsignedByte"]):
                    xValue = sValue = _INT(value)
                    if ((baseXsdType in set([u"nonNegativeInteger",u"unsignedLong",u"unsignedInt"]) 
                         and xValue < 0) or
                        (baseXsdType == u"nonPositiveInteger" and xValue > 0) or
                        (baseXsdType == u"positiveInteger" and xValue <= 0) or
                        (baseXsdType == u"byte" and not -128 <= xValue < 127) or
                        (baseXsdType == u"unsignedByte" and not 0 <= xValue < 255) or
                        (baseXsdType == u"short" and not -32768 <= xValue < 32767) or
                        (baseXsdType == u"unsignedShort" and not 0 <= xValue < 65535) or
                        (baseXsdType == u"positiveInteger" and xValue <= 0)):
                        raise ValueError(u"{0} is not {1}".format(value, baseXsdType))
                    if facets:
                        if u"totalDigits" in facets and len(value.replace(u".",u"")) > facets[u"totalDigits"]:
                            raise ValueError(u"totalDigits facet {0}".format(facets[u"totalDigits"]))
                        if u"fractionDigits" in facets and ( u'.' in value and
                            len(value[value.index(u'.') + 1:]) > facets[u"fractionDigits"]):
                            raise ValueError(u"fraction digits facet {0}".format(facets[u"fractionDigits"]))
                        if u"maxInclusive" in facets and xValue > facets[u"maxInclusive"]:
                            raise ValueError(u" > maxInclusive {0}".format(facets[u"maxInclusive"]))
                        if u"maxExclusive" in facets and xValue >= facets[u"maxExclusive"]:
                            raise ValueError(u" >= maxInclusive {0}".format(facets[u"maxExclusive"]))
                        if u"minInclusive" in facets and xValue < facets[u"minInclusive"]:
                            raise ValueError(u" < minInclusive {0}".format(facets[u"minInclusive"]))
                        if u"minExclusive" in facets and xValue <= facets[u"minExclusive"]:
                            raise ValueError(u" <= minExclusive {0}".format(facets[u"minExclusive"]))
                elif baseXsdType == u"boolean":
                    if value in (u"true", u"1"):  
                        xValue = sValue = True
                    elif value in (u"false", u"0"): 
                        xValue = sValue = False
                    else: raise ValueError
                elif baseXsdType == u"QName":
                    xValue = qnameEltPfxName(elt, value, prefixException=ValueError)
                    #xValue = qname(elt, value, castException=ValueError, prefixException=ValueError)
                    sValue = value
                    u''' not sure here, how are explicitDimensions validated, but bad units not?
                    if xValue.namespaceURI in modelXbrl.namespaceDocs:
                        if (xValue not in modelXbrl.qnameConcepts and 
                            xValue not in modelXbrl.qnameTypes and
                            xValue not in modelXbrl.qnameAttributes and
                            xValue not in modelXbrl.qnameAttributeGroups):
                            raise ValueError("qname not defined " + str(xValue))
                    '''
                elif baseXsdType in (u"XBRLI_DECIMALSUNION", u"XBRLI_PRECISIONUNION"):
                    xValue = sValue = value if value == u"INF" else _INT(value)
                elif baseXsdType in (u"XBRLI_NONZERODECIMAL"):
                    xValue = sValue = _INT(value)
                    if xValue == 0:
                        raise ValueError(u"invalid value")
                elif baseXsdType == u"XBRLI_DATEUNION":
                    xValue = dateTime(value, type=DATEUNION, castException=ValueError)
                    sValue = value
                elif baseXsdType == u"dateTime":
                    xValue = dateTime(value, type=DATETIME, castException=ValueError)
                    sValue = value
                elif baseXsdType == u"date":
                    xValue = dateTime(value, type=DATE, castException=ValueError)
                    sValue = value
                elif baseXsdType == u"regex-pattern":
                    # for facet compiling
                    try:
                        sValue = value
                        if value in xmlSchemaPatterns:
                            xValue = xmlSchemaPatterns[value]
                        else:
                            if ur"\i" in value or ur"\c" in value:
                                value = value.replace(ur"\i", iNameChar).replace(ur"\c", cNameChar)
                            xValue = re_compile(value + u"$") # must match whole string
                    except Exception, err:
                        raise ValueError(err)
                else:
                    if baseXsdType in lexicalPatterns:
                        match = lexicalPatterns[baseXsdType].match(value)
                        if match is None:
                            raise ValueError(u"lexical pattern mismatch")
                        if baseXsdType == u"gMonthDay":
                            month, day, zSign, zHrMin, zHr, zMin = match.groups()
                            if int(day) > {2:29, 4:30, 6:30, 9:30, 11:30, 1:31, 3:31, 5:31, 7:31, 8:31, 10:31, 12:31}[int(month)]:
                                raise ValueError(u"invalid day {0} for month {1}".format(day, month))
                            xValue = gMonthDay(month, day)
                        elif baseXsdType == u"gYearMonth":
                            year, month, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gYearMonth(year, month)
                        elif baseXsdType == u"gYear":
                            year, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gYear(year)
                        elif baseXsdType == u"gMonth":
                            month, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gMonth(month)
                        elif baseXsdType == u"gDay":
                            day, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gDay(day)
                        else:
                            xValue = value
                    else: # no lexical pattern, forget compiling value
                        xValue = value
                    sValue = value
Ejemplo n.º 9
0
 def atomize(self, p, x):
     # sequence
     if hasattr(x, '__iter__') and not isinstance(x, str):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, range):
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelObject.ModelFact):
         if x.isTuple:
             raise XPathException(
                 p, 'err:FOTY0012',
                 _('Atomizing tuple {0} that does not have a typed value').
                 format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value  # resolves default value
         e = x.element
     else:
         if isinstance(x, ModelObject.ModelObject):
             e = x.element
         elif isinstance(x, xml.dom.Node):
             e = x
         if e:
             if x.nodeType == xml.dom.Node.ELEMENT_NODE:
                 if e.getAttributeNS(XbrlConst.xsi, "nil") == "true":
                     return []
                 modelXbrl = x.ownerDocument.modelDocument.modelXbrl
                 modelConcept = modelXbrl.qnameConcepts.get(qname(x))
                 if modelConcept:
                     baseXsdType = modelConcept.baseXsdType
                 v = XmlUtil.text(x)
             elif x.nodeType == xml.dom.Node.ATTRIBUTE_NODE:
                 e = x.ownerElement
                 modelXbrl = e.ownerDocument.modelDocument.modelXbrl
                 if x.namespaceURI:
                     attrQname = qname(x.namespaceURI, x.localName)
                 else:
                     attrQname = qname(x.localName)
                 modelConcept = modelXbrl.qnameConcepts.get(qname(e))
                 if modelConcept:
                     baseXsdType = modelConcept.baseXsdAttrType(
                         attrQname) if modelConcept else None
                 if baseXsdType is None:
                     attrObject = modelXbrl.qnameAttributes.get(attrQname)
                     if attrObject:
                         baseXsdType = attrObject.baseXsdType
                 v = x.value
     if baseXsdType in ("decimal", "float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to a {1} does not have a proper value').
                 format(x, baseXsdType))
     elif baseXsdType in ("integer", ):
         try:
             x = int(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to an integer does not have a proper value'
                   ).format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString", "token", "language",
                          "NMTOKEN", "Name", "NCName", "ID", "IDREF",
                          "ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType:
         x = str(v)
     return x
Ejemplo n.º 10
0
 def atomize(self, p, x):
     # sequence
     if isinstance(x, (tuple,list,set)):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, range): 
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelFact):
         if x.isTuple:
             raise XPathException(p, 'err:FOTY0012', _('Atomizing tuple {0} that does not have a typed value').format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value # resolves default value
         e = x
     elif isinstance(x, ModelAttribute): # ModelAttribute is a tuple (below), check this first!
         return x.xValue
     else:
         if isinstance(x, ModelObject):
             e = x
         if e is not None:
             if e.get("{http://www.w3.org/2001/XMLSchema-instance}nil") == "true":
                 return []
             try:
                 if e.xValid >= VALID:
                     return e.xValue
             except AttributeError:
                 pass
             modelXbrl = x.modelXbrl
             modelConcept = modelXbrl.qnameConcepts.get(qname(x))
             if modelConcept is not None:
                 baseXsdType = modelConcept.baseXsdType
             v = XmlUtil.text(x)
     if baseXsdType in ("decimal", "float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to a {1} does not have a proper value').format(x,baseXsdType))
     elif baseXsdType in ("integer",):
         try:
             x = int(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to an integer does not have a proper value').format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e is not None:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString","token","language","NMTOKEN","Name","NCName","ID","IDREF","ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType:
         x = str(v)
     return x
Ejemplo n.º 11
0
def validateValue(modelXbrl, elt, attrTag, baseXsdType, value, isNillable=False, facets=None):
    if baseXsdType:
        try:
            if (len(value) == 0 and
                not attrTag is None and 
                not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace and baseXsdType != "string")
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {"preserve":(False,False), "replace":(True,False), "collapse":(False,True)}
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value.strip())
            if pattern is not None and pattern.match(value) is None:
                    raise ValueError("pattern facet " + facets["pattern"].pattern if facets and "pattern" in facets else "pattern mismatch")
            if facets:
                if "enumeration" in facets and value not in facets["enumeration"]:
                    raise ValueError("{0} is not in {1}".format(value, facets["enumeration"]))
                if "length" in facets and len(value) != facets["length"]:
                    raise ValueError("length {0}, expected {1}".format(len(value), facets["length"]))
                if "minLength" in facets and len(value) < facets["minLength"]:
                    raise ValueError("length {0}, minLength {1}".format(len(value), facets["minLength"]))
                if "maxLength" in facets and len(value) > facets["maxLength"]:
                    raise ValueError("length {0}, maxLength {1}".format(len(value), facets["maxLength"]))
            if baseXsdType == "noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError("value content not permitted")
                xValue = sValue = None
            elif baseXsdType in {"string", "normalizedString", "language", "token", "NMTOKEN","Name","NCName","IDREF","ENTITY"}:
                xValue = sValue = value
            elif baseXsdType == "ID":
                xValue = sValue = value
                xValid = VALID_ID
            elif baseXsdType == "anyURI":
                xValue = anyURI(value)
                sValue = value
                if xValue and not UrlUtil.isValid(xValue):  # allow empty strings to be valid anyURIs
                    raise ValueError("invalid anyURI value")
            elif not value: # rest of types get None if nil/empty value
                xValue = sValue = None
            elif baseXsdType in ("decimal", "float", "double"):
                xValue = sValue = float(value)
                if facets:
                    if "totalDigits" in facets and len(value.replace(".","")) > facets["totalDigits"]:
                        raise ValueError("totalDigits facet {0}".format(facets["totalDigits"]))
                    if "fractionDigits" in facets and ( '.' in value and
                        len(value[value.index('.') + 1:]) > facets["fractionDigits"]):
                        raise ValueError("fraction digits facet {0}".format(facets["fractionDigits"]))
            elif baseXsdType in {"integer",
                                 "nonPositiveInteger","negativeInteger","nonNegativeInteger","positiveInteger",
                                 "long","unsignedLong",
                                 "int","unsignedInt",
                                 "short","unsignedShort",
                                 "byte","unsignedByte"}:
                xValue = sValue = int(value)
                if ((baseXsdType in {"nonNegativeInteger","unsignedLong","unsignedInt"} 
                     and xValue < 0) or
                    (baseXsdType == "nonPositiveInteger" and xValue > 0) or
                    (baseXsdType == "positiveInteger" and xValue <= 0) or
                    (baseXsdType == "byte" and not -128 <= xValue < 127) or
                    (baseXsdType == "unsignedByte" and not 0 <= xValue < 255) or
                    (baseXsdType == "short" and not -32768 <= xValue < 32767) or
                    (baseXsdType == "unsignedShort" and not 0 <= xValue < 65535) or
                    (baseXsdType == "positiveInteger" and xValue <= 0)):
                    raise ValueError("{0} is not {1}".format(value, baseXsdType))
            elif baseXsdType == "boolean":
                if value in ("true", "1"):  
                    xValue = sValue = True
                elif value in ("false", "0"): 
                    xValue = sValue = False
                else: raise ValueError
            elif baseXsdType == "QName":
                xValue = qname(elt, value, castException=ValueError)
                sValue = value
                ''' not sure here, how are explicitDimensions validated, but bad units not?
                if xValue.namespaceURI in modelXbrl.namespaceDocs:
                    if (xValue not in modelXbrl.qnameConcepts and 
                        xValue not in modelXbrl.qnameTypes and
                        xValue not in modelXbrl.qnameAttributes and
                        xValue not in modelXbrl.qnameAttributeGroups):
                        raise ValueError("qname not defined " + str(xValue))
                '''
            elif baseXsdType in ("XBRLI_DECIMALSUNION", "XBRLI_PRECISIONUNION"):
                xValue = sValue = value if value == "INF" else int(value)
            elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                xValue = sValue = int(value)
                if xValue == 0:
                    raise ValueError("invalid value")
            elif baseXsdType == "XBRLI_DATEUNION":
                xValue = dateTime(value, type=DATEUNION, castException=ValueError)
                sValue = value
            elif baseXsdType == "dateTime":
                xValue = dateTime(value, type=DATETIME, castException=ValueError)
                sValue = value
            elif baseXsdType == "date":
                xValue = dateTime(value, type=DATE, castException=ValueError)
                sValue = value
            elif baseXsdType == "regex-pattern":
                # for facet compiling
                try:
                    xValue = re.compile(value + "$") # must match whole string
                    sValue = value
                except Exception as err:
                    raise ValueError(err)
            else:
                if baseXsdType in lexicalPatterns:
                    match = lexicalPatterns[baseXsdType].match(value)
                    if match is None:
                        raise ValueError("lexical pattern mismatch")
                    if baseXsdType == "gMonthDay":
                        month, day, zSign, zHrMin, zHr, zMin = match.groups()
                        if int(day) > {2:29, 4:30, 6:30, 9:30, 11:30, 1:31, 3:31, 5:31, 7:31, 8:31, 10:31, 12:31}[int(month)]:
                            raise ValueError("invalid day {0} for month {1}".format(day, month))
                xValue = value
                sValue = value
        except ValueError as err:
            if ModelInlineFact is not None and isinstance(elt, ModelInlineFact):
                errElt = "{0} fact {1}".format(elt.elementQname, elt.qname)
            else:
                errElt = elt.elementQname
            if attrTag:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"),
                    modelObject=elt,
                    element=errElt,
                    attribute=XmlUtil.clarkNotationToPrefixedName(elt,attrTag,isAttribute=True),
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            else:
                modelXbrl.error("xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s, %(error)s"),
                    modelObject=elt,
                    element=errElt,
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        try:  # dynamically allocate attributes (otherwise given shared empty set)
            xAttributes = elt.xAttributes
        except AttributeError:
            elt.xAttributes = xAttributes = {}
        xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue, sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 12
0
def validateValue(modelXbrl,
                  elt,
                  attrTag,
                  baseXsdType,
                  value,
                  isNillable=False,
                  isNil=False,
                  facets=None):
    if baseXsdType:
        try:
            '''
            if (len(value) == 0 and attrTag is None and not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            '''
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace
                                  and baseXsdType != "string")
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {
                        "preserve": (False, False),
                        "replace": (True, False),
                        "collapse": (False, True)
                    }[facets["whiteSpace"]]
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value.strip())
            if pattern is not None and pattern.match(value) is None:
                raise ValueError("pattern facet " +
                                 facets["pattern"].pattern if facets and
                                 "pattern" in facets else "pattern mismatch")
            if facets:
                if "enumeration" in facets and value not in facets[
                        "enumeration"]:
                    raise ValueError("{0} is not in {1}".format(
                        value, facets["enumeration"]))
                if "length" in facets and len(value) != facets["length"]:
                    raise ValueError("length {0}, expected {1}".format(
                        len(value), facets["length"]))
                if "minLength" in facets and len(value) < facets["minLength"]:
                    raise ValueError("length {0}, minLength {1}".format(
                        len(value), facets["minLength"]))
                if "maxLength" in facets and len(value) > facets["maxLength"]:
                    raise ValueError("length {0}, maxLength {1}".format(
                        len(value), facets["maxLength"]))
            if baseXsdType == "noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError("value content not permitted")
                xValue = sValue = None
            elif baseXsdType in {
                    "string", "normalizedString", "language", "token",
                    "NMTOKEN", "Name", "NCName", "IDREF", "ENTITY"
            }:
                xValue = sValue = value
            elif baseXsdType == "ID":
                xValue = sValue = value
                xValid = VALID_ID
            elif baseXsdType == "anyURI":
                if value:  # allow empty strings to be valid anyURIs
                    if UrlUtil.relativeUrlPattern.match(value) is None:
                        raise ValueError("IETF RFC 2396 4.3 syntax")
                # encode PSVI xValue similarly to Xerces and other implementations
                xValue = anyURI(UrlUtil.anyUriQuoteForPSVI(value))
                sValue = value
            elif not value and isNil and isNillable:  # rest of types get None if nil/empty value
                xValue = sValue = None
            elif baseXsdType in ("decimal", "float", "double"):
                xValue = sValue = float(value)
                if facets:
                    if "totalDigits" in facets and len(value.replace(
                            ".", "")) > facets["totalDigits"]:
                        raise ValueError("totalDigits facet {0}".format(
                            facets["totalDigits"]))
                    if "fractionDigits" in facets and (
                            '.' in value and len(value[value.index('.') + 1:])
                            > facets["fractionDigits"]):
                        raise ValueError("fraction digits facet {0}".format(
                            facets["fractionDigits"]))
                    if "maxInclusive" in facets and xValue > facets[
                            "maxInclusive"]:
                        raise ValueError(" > maxInclusive {0}".format(
                            facets["maxInclusive"]))
                    if "maxExclusive" in facets and xValue >= facets[
                            "maxExclusive"]:
                        raise ValueError(" >= maxInclusive {0}".format(
                            facets["maxExclusive"]))
                    if "minInclusive" in facets and xValue < facets[
                            "minInclusive"]:
                        raise ValueError(" < minInclusive {0}".format(
                            facets["minInclusive"]))
                    if "minExclusive" in facets and xValue <= facets[
                            "minExclusive"]:
                        raise ValueError(" <= minExclusive {0}".format(
                            facets["minExclusive"]))
            elif baseXsdType in {
                    "integer", "nonPositiveInteger", "negativeInteger",
                    "nonNegativeInteger", "positiveInteger", "long",
                    "unsignedLong", "int", "unsignedInt", "short",
                    "unsignedShort", "byte", "unsignedByte"
            }:
                xValue = sValue = _INT(value)
                if ((baseXsdType
                     in {"nonNegativeInteger", "unsignedLong", "unsignedInt"}
                     and xValue < 0)
                        or (baseXsdType == "nonPositiveInteger" and xValue > 0)
                        or (baseXsdType == "positiveInteger" and xValue <= 0)
                        or (baseXsdType == "byte" and not -128 <= xValue < 127)
                        or
                    (baseXsdType == "unsignedByte" and not 0 <= xValue < 255)
                        or
                    (baseXsdType == "short" and not -32768 <= xValue < 32767)
                        or (baseXsdType == "unsignedShort"
                            and not 0 <= xValue < 65535)
                        or (baseXsdType == "positiveInteger" and xValue <= 0)):
                    raise ValueError("{0} is not {1}".format(
                        value, baseXsdType))
                if facets:
                    if "totalDigits" in facets and len(value.replace(
                            ".", "")) > facets["totalDigits"]:
                        raise ValueError("totalDigits facet {0}".format(
                            facets["totalDigits"]))
                    if "fractionDigits" in facets and (
                            '.' in value and len(value[value.index('.') + 1:])
                            > facets["fractionDigits"]):
                        raise ValueError("fraction digits facet {0}".format(
                            facets["fractionDigits"]))
                    if "maxInclusive" in facets and xValue > facets[
                            "maxInclusive"]:
                        raise ValueError(" > maxInclusive {0}".format(
                            facets["maxInclusive"]))
                    if "maxExclusive" in facets and xValue >= facets[
                            "maxExclusive"]:
                        raise ValueError(" >= maxInclusive {0}".format(
                            facets["maxExclusive"]))
                    if "minInclusive" in facets and xValue < facets[
                            "minInclusive"]:
                        raise ValueError(" < minInclusive {0}".format(
                            facets["minInclusive"]))
                    if "minExclusive" in facets and xValue <= facets[
                            "minExclusive"]:
                        raise ValueError(" <= minExclusive {0}".format(
                            facets["minExclusive"]))
            elif baseXsdType == "boolean":
                if value in ("true", "1"):
                    xValue = sValue = True
                elif value in ("false", "0"):
                    xValue = sValue = False
                else:
                    raise ValueError
            elif baseXsdType == "QName":
                xValue = qname(elt,
                               value,
                               castException=ValueError,
                               prefixException=ValueError)
                sValue = value
                ''' not sure here, how are explicitDimensions validated, but bad units not?
                if xValue.namespaceURI in modelXbrl.namespaceDocs:
                    if (xValue not in modelXbrl.qnameConcepts and 
                        xValue not in modelXbrl.qnameTypes and
                        xValue not in modelXbrl.qnameAttributes and
                        xValue not in modelXbrl.qnameAttributeGroups):
                        raise ValueError("qname not defined " + str(xValue))
                '''
            elif baseXsdType in ("XBRLI_DECIMALSUNION",
                                 "XBRLI_PRECISIONUNION"):
                xValue = sValue = value if value == "INF" else _INT(value)
            elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                xValue = sValue = _INT(value)
                if xValue == 0:
                    raise ValueError("invalid value")
            elif baseXsdType == "XBRLI_DATEUNION":
                xValue = dateTime(value,
                                  type=DATEUNION,
                                  castException=ValueError)
                sValue = value
            elif baseXsdType == "dateTime":
                xValue = dateTime(value,
                                  type=DATETIME,
                                  castException=ValueError)
                sValue = value
            elif baseXsdType == "date":
                xValue = dateTime(value, type=DATE, castException=ValueError)
                sValue = value
            elif baseXsdType == "regex-pattern":
                # for facet compiling
                try:
                    sValue = value
                    if value in xmlSchemaPatterns:
                        xValue = xmlSchemaPatterns[value]
                    else:
                        if r"\i" in value or r"\c" in value:
                            value = value.replace(r"\i", iNameChar).replace(
                                r"\c", cNameChar)
                        xValue = re.compile(value +
                                            "$")  # must match whole string
                except Exception as err:
                    raise ValueError(err)
            else:
                if baseXsdType in lexicalPatterns:
                    match = lexicalPatterns[baseXsdType].match(value)
                    if match is None:
                        raise ValueError("lexical pattern mismatch")
                    if baseXsdType == "gMonthDay":
                        month, day, zSign, zHrMin, zHr, zMin = match.groups()
                        if int(day) > {
                                2: 29,
                                4: 30,
                                6: 30,
                                9: 30,
                                11: 30,
                                1: 31,
                                3: 31,
                                5: 31,
                                7: 31,
                                8: 31,
                                10: 31,
                                12: 31
                        }[int(month)]:
                            raise ValueError(
                                "invalid day {0} for month {1}".format(
                                    day, month))
                xValue = value
                sValue = value
        except ValueError as err:
            if ModelInlineFact is not None and isinstance(
                    elt, ModelInlineFact):
                errElt = "{0} fact {1}".format(elt.elementQname, elt.qname)
            else:
                errElt = elt.elementQname
            if attrTag:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    attribute=XmlUtil.clarkNotationToPrefixedName(
                        elt, attrTag, isAttribute=True),
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            else:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        try:  # dynamically allocate attributes (otherwise given shared empty set)
            xAttributes = elt.xAttributes
        except AttributeError:
            elt.xAttributes = xAttributes = {}
        xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue,
                                              sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 13
0
 def atomize(self, p, x):
     # sequence
     if isinstance(x, (tuple, list, set)):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, _RANGE):
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelFact):
         if x.isTuple:
             raise XPathException(
                 p, 'err:FOTY0012',
                 _('Atomizing tuple {0} that does not have a typed value').
                 format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value  # resolves default value
         e = x
     elif isinstance(
             x, ModelAttribute
     ):  # ModelAttribute is a tuple (below), check this first!
         return x.xValue
     else:
         if isinstance(x, ModelObject):
             e = x
         if e is not None:
             if e.get("{http://www.w3.org/2001/XMLSchema-instance}nil"
                      ) == "true":
                 return []
             try:
                 if e.xValid >= VALID:
                     return e.xValue
             except AttributeError:
                 pass
             modelXbrl = x.modelXbrl
             modelConcept = modelXbrl.qnameConcepts.get(qname(x))
             if modelConcept is not None:
                 baseXsdType = modelConcept.baseXsdType
             v = XmlUtil.text(x)
     if baseXsdType in ("decimal", "float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to a {1} does not have a proper value').
                 format(x, baseXsdType))
     elif baseXsdType in ("integer", ):
         try:
             x = _INT(v)
         except ValueError:
             raise XPathException(
                 p, 'err:FORG0001',
                 _('Atomizing {0} to an integer does not have a proper value'
                   ).format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e is not None:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString", "token", "language",
                          "NMTOKEN", "Name", "NCName", "ID", "IDREF",
                          "ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType:
         x = str(v)
     return x
Ejemplo n.º 14
0
def validateValue(modelXbrl,
                  elt,
                  attrTag,
                  baseXsdType,
                  value,
                  isNillable=False,
                  isNil=False,
                  facets=None):
    if baseXsdType:
        try:
            '''
            if (len(value) == 0 and attrTag is None and not isNillable and 
                baseXsdType not in ("anyType", "string", "normalizedString", "token", "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            '''
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace
                                  and baseXsdType != "string")
            isList = baseXsdType in {"IDREFS", "ENTITIES", "NMTOKENS"}
            if isList:
                baseXsdType = baseXsdType[:-1]  # remove plural
                if facets:
                    if "minLength" not in facets:
                        facets = facets.copy()
                        facets["minLength"] = 1
                else:
                    facets = {"minLength": 1}
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {
                        "preserve": (False, False),
                        "replace": (True, False),
                        "collapse": (False, True)
                    }[facets["whiteSpace"]]
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(
                    ' ', value)  # replace tab, line feed, return with space
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value).strip(
                    ' '
                )  # collapse multiple spaces, tabs, line feeds and returns to single space
            if baseXsdType == "noContent":
                if len(value) > 0 and not entirelyWhitespacePattern.match(
                        value):  # only xml schema pattern whitespaces removed
                    raise ValueError("value content not permitted")
                # note that sValue and xValue are not innerText but only text elements on specific element (or attribute)
                xValue = sValue = None
                xValid = VALID_NO_CONTENT  # notify others that element may contain subelements (for stringValue needs)
            elif not value and isNil and isNillable:  # rest of types get None if nil/empty value
                xValue = sValue = None
            else:
                if pattern is not None:
                    if ((isList and any(
                            pattern.match(v) is None for v in value.split()))
                            or (not isList and pattern.match(value) is None)):
                        raise ValueError(
                            "pattern facet " +
                            facets["pattern"].pattern if facets
                            and "pattern" in facets else "pattern mismatch")
                if facets:
                    if "enumeration" in facets and value not in facets[
                            "enumeration"]:
                        raise ValueError("{0} is not in {1}".format(
                            value, facets["enumeration"].keys()))
                    if "length" in facets and len(value) != facets["length"]:
                        raise ValueError("length {0}, expected {1}".format(
                            len(value), facets["length"]))
                    if "minLength" in facets and len(
                            value) < facets["minLength"]:
                        raise ValueError("length {0}, minLength {1}".format(
                            len(value), facets["minLength"]))
                    if "maxLength" in facets and len(
                            value) > facets["maxLength"]:
                        raise ValueError("length {0}, maxLength {1}".format(
                            len(value), facets["maxLength"]))
                if baseXsdType in {
                        "string", "normalizedString", "language",
                        "languageOrEmpty", "token", "NMTOKEN", "Name",
                        "NCName", "IDREF", "ENTITY"
                }:
                    xValue = sValue = value
                elif baseXsdType == "ID":
                    xValue = sValue = value
                    xValid = VALID_ID
                elif baseXsdType == "anyURI":
                    if value:  # allow empty strings to be valid anyURIs
                        if UrlUtil.relativeUrlPattern.match(value) is None:
                            raise ValueError("IETF RFC 2396 4.3 syntax")
                    # encode PSVI xValue similarly to Xerces and other implementations
                    xValue = anyURI(UrlUtil.anyUriQuoteForPSVI(value))
                    sValue = value
                elif baseXsdType in ("decimal", "float", "double",
                                     "XBRLI_NONZERODECIMAL"):
                    if baseXsdType in ("decimal", "XBRLI_NONZERODECIMAL"):
                        if decimalPattern.match(value) is None:
                            raise ValueError("lexical pattern mismatch")
                        xValue = Decimal(value)
                        sValue = float(
                            value
                        )  # s-value uses Number (float) representation
                        if sValue == 0 and baseXsdType == "XBRLI_NONZERODECIMAL":
                            raise ValueError("zero is not allowed")
                    else:
                        if floatPattern.match(value) is None:
                            raise ValueError("lexical pattern mismatch")
                        xValue = sValue = float(value)
                    if facets:
                        if "totalDigits" in facets and len(
                                value.replace(".",
                                              "")) > facets["totalDigits"]:
                            raise ValueError("totalDigits facet {0}".format(
                                facets["totalDigits"]))
                        if "fractionDigits" in facets and (
                                '.' in value
                                and len(value[value.index('.') + 1:]) >
                                facets["fractionDigits"]):
                            raise ValueError(
                                "fraction digits facet {0}".format(
                                    facets["fractionDigits"]))
                        if "maxInclusive" in facets and xValue > facets[
                                "maxInclusive"]:
                            raise ValueError(" > maxInclusive {0}".format(
                                facets["maxInclusive"]))
                        if "maxExclusive" in facets and xValue >= facets[
                                "maxExclusive"]:
                            raise ValueError(" >= maxInclusive {0}".format(
                                facets["maxExclusive"]))
                        if "minInclusive" in facets and xValue < facets[
                                "minInclusive"]:
                            raise ValueError(" < minInclusive {0}".format(
                                facets["minInclusive"]))
                        if "minExclusive" in facets and xValue <= facets[
                                "minExclusive"]:
                            raise ValueError(" <= minExclusive {0}".format(
                                facets["minExclusive"]))
                elif baseXsdType in {
                        "integer", "nonPositiveInteger", "negativeInteger",
                        "nonNegativeInteger", "positiveInteger", "long",
                        "unsignedLong", "int", "unsignedInt", "short",
                        "unsignedShort", "byte", "unsignedByte"
                }:
                    xValue = sValue = _INT(value)
                    if ((baseXsdType in {
                            "nonNegativeInteger", "unsignedLong", "unsignedInt"
                    } and xValue < 0) or
                        (baseXsdType == "nonPositiveInteger" and xValue > 0) or
                        (baseXsdType == "positiveInteger" and xValue <= 0) or
                        (baseXsdType == "byte" and not -128 <= xValue < 127)
                            or (baseXsdType == "unsignedByte"
                                and not 0 <= xValue < 255)
                            or (baseXsdType == "short"
                                and not -32768 <= xValue < 32767)
                            or (baseXsdType == "unsignedShort"
                                and not 0 <= xValue < 65535) or
                        (baseXsdType == "positiveInteger" and xValue <= 0)):
                        raise ValueError("{0} is not {1}".format(
                            value, baseXsdType))
                    if facets:
                        if "totalDigits" in facets and len(
                                value.replace(".",
                                              "")) > facets["totalDigits"]:
                            raise ValueError("totalDigits facet {0}".format(
                                facets["totalDigits"]))
                        if "fractionDigits" in facets and (
                                '.' in value
                                and len(value[value.index('.') + 1:]) >
                                facets["fractionDigits"]):
                            raise ValueError(
                                "fraction digits facet {0}".format(
                                    facets["fractionDigits"]))
                        if "maxInclusive" in facets and xValue > facets[
                                "maxInclusive"]:
                            raise ValueError(" > maxInclusive {0}".format(
                                facets["maxInclusive"]))
                        if "maxExclusive" in facets and xValue >= facets[
                                "maxExclusive"]:
                            raise ValueError(" >= maxInclusive {0}".format(
                                facets["maxExclusive"]))
                        if "minInclusive" in facets and xValue < facets[
                                "minInclusive"]:
                            raise ValueError(" < minInclusive {0}".format(
                                facets["minInclusive"]))
                        if "minExclusive" in facets and xValue <= facets[
                                "minExclusive"]:
                            raise ValueError(" <= minExclusive {0}".format(
                                facets["minExclusive"]))
                elif baseXsdType == "boolean":
                    if value in ("true", "1"):
                        xValue = sValue = True
                    elif value in ("false", "0"):
                        xValue = sValue = False
                    else:
                        raise ValueError
                elif baseXsdType == "QName":
                    xValue = qnameEltPfxName(elt,
                                             value,
                                             prefixException=ValueError)
                    #xValue = qname(elt, value, castException=ValueError, prefixException=ValueError)
                    sValue = value
                    ''' not sure here, how are explicitDimensions validated, but bad units not?
                    if xValue.namespaceURI in modelXbrl.namespaceDocs:
                        if (xValue not in modelXbrl.qnameConcepts and 
                            xValue not in modelXbrl.qnameTypes and
                            xValue not in modelXbrl.qnameAttributes and
                            xValue not in modelXbrl.qnameAttributeGroups):
                            raise ValueError("qname not defined " + str(xValue))
                    '''
                elif baseXsdType == "enumerationHrefs":
                    xValue = [qnameHref(href) for href in value.split()]
                    sValue = value
                elif baseXsdType == "enumerationQNames":
                    xValue = [
                        qnameEltPfxName(elt, qn, prefixException=ValueError)
                        for qn in value.split()
                    ]
                    sValue = value
                elif baseXsdType in ("XBRLI_DECIMALSUNION",
                                     "XBRLI_PRECISIONUNION"):
                    xValue = sValue = value if value == "INF" else _INT(value)
                elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                    xValue = sValue = _INT(value)
                    if xValue == 0:
                        raise ValueError("invalid value")
                elif baseXsdType == "regex-pattern":
                    # for facet compiling
                    try:
                        sValue = value
                        if value in xmlSchemaPatterns:
                            xValue = xmlSchemaPatterns[value]
                        else:
                            if r"\i" in value or r"\c" in value:
                                value = value.replace(r"[\i-[:]]", iNameChar).replace(r"\i", iNameChar) \
                                              .replace(r"[\c-[:]]", cMinusCNameChar).replace(r"\c", cNameChar)
                            xValue = re_compile(value +
                                                "$")  # must match whole string
                    except Exception as err:
                        raise ValueError(err)
                elif baseXsdType == "fraction":
                    numeratorStr, denominatorStr = elt.fractionValue
                    if numeratorStr == INVALIDixVALUE or denominatorStr == INVALIDixVALUE:
                        sValue = xValue = INVALIDixVALUE
                        xValid = INVALID
                    else:
                        sValue = value
                        numeratorNum = float(numeratorStr)
                        denominatorNum = float(denominatorStr)
                        if numeratorNum.is_integer(
                        ) and denominatorNum.is_integer():
                            xValue = Fraction(int(numeratorNum),
                                              int(denominatorNum))
                        else:
                            xValue = Fraction(numeratorNum / denominatorNum)
                else:
                    if baseXsdType in lexicalPatterns:
                        match = lexicalPatterns[baseXsdType].match(value)
                        if match is None:
                            raise ValueError("lexical pattern mismatch")
                        if baseXsdType == "XBRLI_DATEUNION":
                            xValue = dateTime(value,
                                              type=DATEUNION,
                                              castException=ValueError)
                            sValue = value
                        elif baseXsdType == "dateTime":
                            xValue = dateTime(value,
                                              type=DATETIME,
                                              castException=ValueError)
                            sValue = value
                        elif baseXsdType == "date":
                            xValue = dateTime(value,
                                              type=DATE,
                                              castException=ValueError)
                            sValue = value
                        elif baseXsdType == "gMonthDay":
                            month, day, zSign, zHrMin, zHr, zMin = match.groups(
                            )
                            if int(day) > {
                                    2: 29,
                                    4: 30,
                                    6: 30,
                                    9: 30,
                                    11: 30,
                                    1: 31,
                                    3: 31,
                                    5: 31,
                                    7: 31,
                                    8: 31,
                                    10: 31,
                                    12: 31
                            }[int(month)]:
                                raise ValueError(
                                    "invalid day {0} for month {1}".format(
                                        day, month))
                            xValue = gMonthDay(month, day)
                        elif baseXsdType == "gYearMonth":
                            year, month, zSign, zHrMin, zHr, zMin = match.groups(
                            )
                            xValue = gYearMonth(year, month)
                        elif baseXsdType == "gYear":
                            year, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gYear(year)
                        elif baseXsdType == "gMonth":
                            month, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gMonth(month)
                        elif baseXsdType == "gDay":
                            day, zSign, zHrMin, zHr, zMin = match.groups()
                            xValue = gDay(day)
                        elif baseXsdType == "duration":
                            xValue = isoDuration(value)
                        else:
                            xValue = value
                    else:  # no lexical pattern, forget compiling value
                        xValue = value
                    sValue = value
        except (ValueError, InvalidOperation) as err:
            if ModelInlineValueObject is not None and isinstance(
                    elt, ModelInlineValueObject):
                errElt = "{0} fact {1}".format(elt.elementQname, elt.qname)
            else:
                errElt = elt.elementQname
            if attrTag:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    attribute=XmlUtil.clarkNotationToPrefixedName(
                        elt, attrTag, isAttribute=True),
                    typeName=baseXsdType,
                    value=strTruncate(value, 30),
                    error=err)
            else:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    typeName=baseXsdType,
                    value=strTruncate(value, 30),
                    error=err)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        try:  # dynamically allocate attributes (otherwise given shared empty set)
            xAttributes = elt.xAttributes
        except AttributeError:
            elt.xAttributes = xAttributes = {}
        xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue,
                                              sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 15
0
 def atomize(self, p, x):
     # sequence
     if isinstance(x, SEQUENCE_TYPES):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, _RANGE): 
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelFact):
         if x.isTuple:
             raise XPathException(p, 'err:FOTY0012', _('Atomizing tuple {0} that does not have a typed value').format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value # resolves default value
         e = x
     elif isinstance(x, ModelAttribute): # ModelAttribute is a tuple (below), check this first!
         return x.xValue
     else:
         if isinstance(x, ModelObject):
             e = x
         if e is not None:
             if getattr(e, "xValid", 0) == VALID_NO_CONTENT:
                 raise XPathException(p, 'err:FOTY0012', _('Atomizing element {0} that does not have a typed value').format(x))
             if e.get("{http://www.w3.org/2001/XMLSchema-instance}nil") == "true":
                 return []
             try:
                 if e.xValid >= VALID:
                     return e.xValue
             except AttributeError:
                 pass
             modelXbrl = x.modelXbrl
             modelConcept = modelXbrl.qnameConcepts.get(qname(x))
             if modelConcept is not None:
                 baseXsdType = modelConcept.baseXsdType
             v = x.stringValue
     if baseXsdType in ("float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to a {1} does not have a proper value').format(x,baseXsdType))
     elif baseXsdType == "decimal":
         try:
             x = Decimal(v)
         except InvalidOperation:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to decimal does not have a proper value'))
     elif baseXsdType in ("integer",
                          "nonPositiveInteger","negativeInteger","nonNegativeInteger","positiveInteger",
                          "long","unsignedLong",
                          "int","unsignedInt",
                          "short","unsignedShort",
                          "byte","unsignedByte"):
         try:
             x = _INT(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to an integer does not have a proper value').format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e is not None:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString","token","language","NMTOKEN","Name","NCName","ID","IDREF","ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType == "noContent":
         x = None # can't be atomized
     elif baseXsdType:
         x = str(v)
     return x
Ejemplo n.º 16
0
def validateValue(modelXbrl,
                  elt,
                  attrTag,
                  baseXsdType,
                  value,
                  isNillable=False,
                  facets=None):
    if baseXsdType:
        try:
            if (len(value) == 0 and not attrTag is None and not isNillable
                    and baseXsdType
                    not in ("anyType", "string", "normalizedString", "token",
                            "NMTOKEN", "anyURI", "noContent")):
                raise ValueError("missing value for not nillable element")
            xValid = VALID
            whitespaceReplace = (baseXsdType == "normalizedString")
            whitespaceCollapse = (not whitespaceReplace
                                  and baseXsdType != "string")
            pattern = baseXsdTypePatterns.get(baseXsdType)
            if facets:
                if "pattern" in facets:
                    pattern = facets["pattern"]
                    # note multiple patterns are or'ed togetner, which isn't yet implemented!
                if "whiteSpace" in facets:
                    whitespaceReplace, whitespaceCollapse = {
                        "preserve": (False, False),
                        "replace": (True, False),
                        "collapse": (False, True)
                    }
            if whitespaceReplace:
                value = normalizeWhitespacePattern.sub(' ', value)
            elif whitespaceCollapse:
                value = collapseWhitespacePattern.sub(' ', value.strip())
            if pattern is not None and pattern.match(value) is None:
                raise ValueError("pattern facet " +
                                 facets["pattern"].pattern if facets and
                                 "pattern" in facets else "pattern mismatch")
            if facets:
                if "enumeration" in facets and value not in facets[
                        "enumeration"]:
                    raise ValueError("is not in {1}".format(
                        value, facets["enumeration"]))
                if "length" in facets and len(value) != facets["length"]:
                    raise ValueError("length {0}, expected {1}".format(
                        len(value), facets["length"]))
                if "minLength" in facets and len(value) < facets["minLength"]:
                    raise ValueError("length {0}, minLength {1}".format(
                        len(value), facets["minLength"]))
                if "maxLength" in facets and len(value) > facets["maxLength"]:
                    raise ValueError("length {0}, maxLength {1}".format(
                        len(value), facets["maxLength"]))
            if baseXsdType == "noContent":
                if len(value) > 0 and not value.isspace():
                    raise ValueError("value content not permitted")
                xValue = sValue = None
            elif baseXsdType in {
                    "string", "normalizedString", "language", "token",
                    "NMTOKEN", "Name", "NCName", "IDREF", "ENTITY"
            }:
                xValue = sValue = value
            elif baseXsdType == "ID":
                xValue = sValue = value
                xValid = VALID_ID
            elif baseXsdType == "anyURI":
                xValue = anyURI(value)
                sValue = value
                if xValue and not UrlUtil.isValid(
                        xValue):  # allow empty strings to be valid anyURIs
                    raise ValueError("invalid anyURI value")
            elif not value:  # rest of types get None if nil/empty value
                xValue = sValue = None
            elif baseXsdType in ("decimal", "float", "double"):
                xValue = sValue = float(value)
                if facets:
                    if "totalDigits" in facets and len(value.replace(
                            ".", "")) > facets["totalDigits"]:
                        raise ValueError("totalDigits facet {0}".format(
                            facets["totalDigits"]))
                    if "fractionDigits" in facets and (
                            '.' in value and len(value[value.index('.') + 1:])
                            > facets["fractionDigits"]):
                        raise ValueError("fraction digits facet {0}".format(
                            facets["fractionDigits"]))
            elif baseXsdType in ("integer", ):
                xValue = sValue = int(value)
            elif baseXsdType == "boolean":
                if value in ("true", "1"):
                    xValue = sValue = True
                elif value in ("false", "0"):
                    xValue = sValue = False
                else:
                    raise ValueError
            elif baseXsdType == "QName":
                xValue = qname(elt, value, castException=ValueError)
                sValue = value
                ''' not sure here, how are explicitDimensions validated, but bad units not?
                if xValue.namespaceURI in modelXbrl.namespaceDocs:
                    if (xValue not in modelXbrl.qnameConcepts and 
                        xValue not in modelXbrl.qnameTypes and
                        xValue not in modelXbrl.qnameAttributes and
                        xValue not in modelXbrl.qnameAttributeGroups):
                        raise ValueError("qname not defined " + str(xValue))
                '''
            elif baseXsdType in ("XBRLI_DECIMALSUNION",
                                 "XBRLI_PRECISIONUNION"):
                xValue = sValue = value if value == "INF" else int(value)
            elif baseXsdType in ("XBRLI_NONZERODECIMAL"):
                xValue = sValue = int(value)
                if xValue == 0:
                    raise ValueError("invalid value")
            elif baseXsdType == "XBRLI_DATEUNION":
                xValue = dateTime(value,
                                  type=DATEUNION,
                                  castException=ValueError)
                sValue = value
            elif baseXsdType == "dateTime":
                xValue = dateTime(value,
                                  type=DATETIME,
                                  castException=ValueError)
                sValue = value
            elif baseXsdType == "date":
                xValue = dateTime(value, type=DATE, castException=ValueError)
                sValue = value
            elif baseXsdType == "regex-pattern":
                # for facet compiling
                try:
                    xValue = re.compile(value + "$")  # must match whole string
                    sValue = value
                except Exception as err:
                    raise ValueError(err)
            else:
                if baseXsdType in lexicalPatterns:
                    match = lexicalPatterns[baseXsdType].match(value)
                    if match is None:
                        raise ValueError("lexical pattern mismatch")
                    if baseXsdType == "gMonthDay":
                        month, day, zSign, zHrMin, zHr, zMin = match.groups()
                        if int(day) > {
                                2: 29,
                                4: 30,
                                6: 30,
                                9: 30,
                                11: 30,
                                1: 31,
                                3: 31,
                                5: 31,
                                7: 31,
                                8: 31,
                                10: 31,
                                12: 31
                        }[int(month)]:
                            raise ValueError(
                                "invalid day {0} for month {1}".format(
                                    day, month))
                xValue = value
                sValue = value
        except ValueError as err:
            if ModelInlineFact is not None and isinstance(
                    elt, ModelInlineFact):
                errElt = "{0} fact {1}".format(elt.elementQname, elt.qname)
            else:
                errElt = elt.elementQname
            if attrTag:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s attribute %(attribute)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    attribute=XmlUtil.clarkNotationToPrefixedName(
                        elt, attrTag, isAttribute=True),
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            else:
                modelXbrl.error(
                    "xmlSchema:valueError",
                    _("Element %(element)s type %(typeName)s value error: %(value)s, %(error)s"
                      ),
                    modelObject=elt,
                    element=errElt,
                    typeName=baseXsdType,
                    value=value,
                    error=err)
            xValue = None
            sValue = value
            xValid = INVALID
    else:
        xValue = sValue = None
        xValid = UNKNOWN
    if attrTag:
        elt.xAttributes[attrTag] = ModelAttribute(elt, attrTag, xValid, xValue,
                                                  sValue, value)
    else:
        elt.xValid = xValid
        elt.xValue = xValue
        elt.sValue = sValue
Ejemplo n.º 17
0
 def atomize(self, p, x):
     # sequence
     if hasattr(x, '__iter__') and not isinstance(x, str):
         sequence = []
         for item in self.flattenSequence(x):
             atomizedItem = self.atomize(p, item)
             if atomizedItem != []:
                 sequence.append(atomizedItem)
         return sequence
     # individual items
     if isinstance(x, range): 
         return x
     baseXsdType = None
     e = None
     if isinstance(x, ModelObject.ModelFact):
         if x.isTuple:
             raise XPathException(p, 'err:FOTY0012', _('Atomizing tuple {0} that does not have a typed value').format(x))
         if x.isNil:
             return []
         baseXsdType = x.concept.baseXsdType
         v = x.value # resolves default value
         e = x.element
     else:
         if isinstance(x, ModelObject.ModelObject):
             e = x.element
         elif isinstance(x, xml.dom.Node):
             e = x
         if e:
             if x.nodeType == xml.dom.Node.ELEMENT_NODE:
                 if e.getAttributeNS(XbrlConst.xsi,"nil") == "true":
                     return []
                 modelXbrl = x.ownerDocument.modelDocument.modelXbrl
                 modelConcept = modelXbrl.qnameConcepts.get(qname(x))
                 if modelConcept:
                     baseXsdType = modelConcept.baseXsdType
                 v = XmlUtil.text(x)
             elif x.nodeType == xml.dom.Node.ATTRIBUTE_NODE:
                 e = x.ownerElement
                 modelXbrl = e.ownerDocument.modelDocument.modelXbrl
                 if x.namespaceURI:
                     attrQname = qname(x.namespaceURI, x.localName)
                 else:
                     attrQname = qname(x.localName)
                 modelConcept = modelXbrl.qnameConcepts.get(qname(e))
                 if modelConcept:
                     baseXsdType = modelConcept.baseXsdAttrType(attrQname) if modelConcept else None
                 if baseXsdType is None:
                     attrObject = modelXbrl.qnameAttributes.get(attrQname)
                     if attrObject:
                         baseXsdType = attrObject.baseXsdType
                 v = x.value
     if baseXsdType in ("decimal", "float", "double"):
         try:
             x = float(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to a {1} does not have a proper value').format(x,baseXsdType))
     elif baseXsdType in ("integer",):
         try:
             x = int(v)
         except ValueError:
             raise XPathException(p, 'err:FORG0001', _('Atomizing {0} to an integer does not have a proper value').format(x))
     elif baseXsdType == "boolean":
         x = (v == "true" or v == "1")
     elif baseXsdType == "QName" and e:
         x = qname(e, v)
     elif baseXsdType == "anyURI":
         x = anyURI(v.strip())
     elif baseXsdType in ("normalizedString","token","language","NMTOKEN","Name","NCName","ID","IDREF","ENTITY"):
         x = v.strip()
     elif baseXsdType == "XBRLI_DATEUNION":
         x = dateTime(v, type=DATEUNION)
     elif baseXsdType == "date":
         x = dateTime(v, type=DATE)
     elif baseXsdType == "dateTime":
         x = dateTime(v, type=DATETIME)
     elif baseXsdType:
         x = str(v)
     return x