private static SpecificationValue ParseSpecificationValue( XElement element, XmlSchema schema, XmlSchemaSet schemaSet, string ns) { SpecificationValue value; string isRef = GetRef(element, ns); if (isRef != null) { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueReference", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); value = SpecificationValue.Ref(isRef); } else { SpecificationValue.Multiplicity mul = GetMul(element, ns); SpecificationValue.DataType type = GetType(element, ns); string[] values = GetValues(element, ns).ToArray(); if (values.Length <= 1) { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueSingle", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); } else { element.Validate( schema.SchemaTypes[new XmlQualifiedName("valueMultiple", ns)], schemaSet, (sender, args) => throw new ArgumentException(args.Message, args.Exception)); } SpecificationValueSettings settings = ValueSettings.GetOrAdd( (int)mul * 1000 + (int)type, i => new SpecificationValueSettings { AllowCast = true, DefaultMultiplicity = mul, IncludeDetails = true, ExpectedType = type }); if (!SpecificationValue.TryFrom(values, settings, out value, out string error)) { throw new ArgumentException(error); } } return(value); }
public static bool HasMappingOrCast( object value, SpecificationValue.DataType desiredType, SpecificationValueSettings settings, out object result) { result = value; if (value == null) { return(false); } Type type = value.GetType(); if (Mapping.ContainsKey(type)) { SpecificationValue.DataType actualType = Mapping[type]; if (actualType == desiredType) { return(true); } } if (settings.AllowCast) { switch (desiredType) { case SpecificationValue.DataType.DateTime: { if (value is string str) { if (DateTime.TryParseExact( str, "u", DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AssumeUniversal, out DateTime dtv)) { result = dtv; return(true); } } } break; case SpecificationValue.DataType.Int: { if (value is float fv && Math.Round(fv) == fv) { result = (int)fv; return(true); } if (value is string str) { if (int.TryParse(str, out int iv)) { result = iv; return(true); } } } break; case SpecificationValue.DataType.Float: { if (value is int iv) { result = (float)iv; return(true); } if (value is string str) { if (float.TryParse(str, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out float fv)) { result = fv; return(true); } } } break; case SpecificationValue.DataType.String: { if (value is int iv) { result = iv.ToString("D"); } else if (value is float fv) { result = fv.ToString("F"); } else if (value is DateTime dtv) { result = dtv.ToString("u"); } else { result = value.ToString(); } return(true); } default: return(false); } } return(false); }
public void FromSingle(object value, object eval, SpecificationValue.Multiplicity sm, bool sac, bool sid, bool er, SpecificationValue.DataType et, SpecificationValue.Multiplicity em, string ee) { bool result = SpecificationValue.TryFrom( value, new SpecificationValueSettings { IncludeDetails = sid, DefaultMultiplicity = sm, AllowCast = sac }, out SpecificationValue specification, out string error); Assert.Equal(er, result); if (result) { Assert.Equal(et, specification.ValueType); Assert.Equal(em, specification.ValueMultiplicity); if (eval != null) { Assert.Contains(eval, specification.Values); } } else { Assert.Null(specification); if (ee == null) { Assert.Null(error); } else { Assert.Contains(ee, error); } } }