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
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
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
def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance( node, (ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException( self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format( op, node)) targetNodes = [] if isinstance(p, QNameDef): ns = p.namespaceURI localname = p.localName axis = p.axis if p.isAttribute: if isinstance(node, ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: xmlValidate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append( ModelAttribute(node, p.clarkNotation, UNKNOWN, value, value, value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if axis is None or axis == "child": if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif axis == "parent": if isinstance(node, ModelAttribute): parentNode = [node.modelElement] else: parentNode = [XmlUtil.parent(node)] if (isinstance(node, ModelObject) and (not ns or ns == parentNode.namespaceURI or ns == "*") and (localname == parentNode.localName or localname == "*")): targetNodes = [parentNode] elif axis == "self": if (isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes = [node] elif axis.startswith("descendant"): if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants( node, ns, localname) if (axis.endswith("-or-self") and isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.append(node) elif axis.startswith("ancestor"): if isinstance(node, ModelObject): targetNodes = [ ancestor for ancestor in XmlUtil.ancestors(node) if ((not ns or ns == ancestor.namespaceURI or ns == "*") and ( localname == ancestor.localName or localname == "*")) ] if (axis.endswith("-or-self") and isinstance(node, ModelObject) and (not ns or ns == node.namespaceURI or ns == "*") and (localname == node.localName or localname == "*")): targetNodes.insert(0, node) elif axis.endswith("-sibling"): if isinstance(node, ModelObject): targetNodes = [ sibling for sibling in node.itersiblings( preceding=axis.startswith("preceding")) if ((not ns or ns == sibling.namespaceURI or ns == "*") and ( localname == sibling.localName or localname == "*")) ] elif axis == "preceding": if isinstance(node, ModelObject): for preceding in node.getroottree().iter(): if preceding == node: break elif ((not ns or ns == preceding.namespaceURI or ns == "*") and (localname == preceding.localName or localname == "*")): targetNodes.append(preceding) elif axis == "following": if isinstance(node, ModelObject): foundNode = False for following in node.getroottree().iter(): if following == node: foundNode = True elif (foundNode and (not ns or ns == following.namespaceURI or ns == "*") and (localname == following.localName or localname == "*")): targetNodes.append(following) elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node, ModelAttribute): targetNodes = [node.modelElement] else: targetNodes = [XmlUtil.parent(node)] elif isinstance(p, OperationDef) and isinstance(p.name, QNameDef): if isinstance(node, ModelObject): if p.name.localName == "text": # note this is not string value, just child text targetNodes = [node.textValue] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence
def stepAxis(self, op, p, sourceSequence): targetSequence = [] for node in sourceSequence: if not isinstance( node, (ModelObject, etree._ElementTree, ModelAttribute)): raise XPathException( self.progHeader, 'err:XPTY0020', _('Axis step {0} context item is not a node: {1}').format( op, node)) targetNodes = [] if isinstance(p, QNameDef): ns = p.namespaceURI localname = p.localName if p.isAttribute: if isinstance(node, ModelObject): attrTag = p.localName if p.unprefixed else p.clarkNotation modelAttribute = None try: modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): # may be lax or deferred validated try: validate(node.modelXbrl, node, p) modelAttribute = node.xAttributes[attrTag] except (AttributeError, TypeError, IndexError, KeyError): pass if modelAttribute is None: value = node.get(attrTag) if value is not None: targetNodes.append( ModelAttribute(node, p.clarkNotation, UNKNOWN, value, value, value)) elif modelAttribute.xValid >= VALID: targetNodes.append(modelAttribute) elif op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, ns, localname) elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, ns, localname) elif op == '..': if isinstance(node, ModelAttribute): targetNodes = [node.modelElement] else: targetNodes = [XmlUtil.parent(node)] elif isinstance(p, OperationDef) and isinstance(p.name, QNameDef): if isinstance(node, ModelObject): if p.name.localName == "text": targetNodes = [XmlUtil.text(node)] # todo: add element, attribute, node, etc... elif p == '*': # wildcard if op == '/' or op is None: if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.children(node, '*', '*') elif op == '//': if isinstance(node, (ModelObject, etree._ElementTree)): targetNodes = XmlUtil.descendants(node, '*', '*') targetSequence.extend(targetNodes) return targetSequence