/// <summary>Returns the validated XML element or attribute's value as the type specified using the <see cref="T:System.Xml.IXmlNamespaceResolver" /> object specified to resolve namespace prefixes.</summary> /// <returns>The value of the validated XML element or attribute as the type requested.</returns> /// <param name="type">The type to return the validated XML element or attribute's value as.</param> /// <param name="nsResolver">The <see cref="T:System.Xml.IXmlNamespaceResolver" /> object used to resolve namespace prefixes.</param> /// <exception cref="T:System.FormatException">The validated XML element or attribute's value is not in the correct format for the target type.</exception> /// <exception cref="T:System.InvalidCastException">The attempted cast is not valid.</exception> /// <exception cref="T:System.OverflowException">The attempted cast resulted in an overflow.</exception> public override object ValueAs(Type type, IXmlNamespaceResolver nsResolver) { XmlTypeCode xmlTypeCode = XmlAtomicValue.XmlTypeCodeFromRuntimeType(type, false); switch (xmlTypeCode) { case XmlTypeCode.Long: case XmlTypeCode.UnsignedInt: return(this.ValueAsLong); case XmlTypeCode.Int: case XmlTypeCode.Short: case XmlTypeCode.UnsignedShort: return(this.ValueAsInt); default: switch (xmlTypeCode) { case XmlTypeCode.String: return(this.Value); case XmlTypeCode.Boolean: return(this.ValueAsBoolean); default: if (xmlTypeCode == XmlTypeCode.Item) { return(this.TypedValue); } if (xmlTypeCode != XmlTypeCode.QName) { throw new NotImplementedException(); } return(XmlQualifiedName.Parse(this.Value, nsResolver, true)); case XmlTypeCode.Float: case XmlTypeCode.Double: return(this.ValueAsDouble); case XmlTypeCode.DateTime: return(this.ValueAsDateTime); } break; } }
private void Init(object value, XmlSchemaType xmlType) { // It accepts any kind of object, but will be rejected on each value properties. if (value == null) { throw new ArgumentNullException("value"); } if (xmlType == null) { throw new ArgumentNullException("xmlType"); } switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Int16: Init((short)value, xmlType); return; case TypeCode.UInt16: Init((ushort)value, xmlType); return; case TypeCode.Int32: Init((int)value, xmlType); return; case TypeCode.Decimal: Init((decimal)value, xmlType); return; case TypeCode.Double: Init((double)value, xmlType); return; case TypeCode.Single: Init((float)value, xmlType); return; case TypeCode.Int64: Init((long)value, xmlType); return; case TypeCode.UInt32: Init((uint)value, xmlType); return; case TypeCode.String: Init((string)value, xmlType); return; case TypeCode.DateTime: Init((DateTime)value, xmlType); return; case TypeCode.Boolean: Init((bool)value, xmlType); return; } ICollection col = value as ICollection; if (col != null && col.Count == 1) { if (col is IList) { Init(((IList)col) [0], xmlType); } else { IEnumerator en = col.GetEnumerator(); if (!en.MoveNext()) { return; } if (en.Current is DictionaryEntry) { Init(((DictionaryEntry)en.Current).Value, xmlType); } else { Init(en.Current, xmlType); } } return; } XmlAtomicValue another = value as XmlAtomicValue; if (another != null) { switch (another.xmlTypeCode) { case XmlTypeCode.Boolean: Init(another.booleanValue, xmlType); return; case XmlTypeCode.DateTime: Init(another.dateTimeValue, xmlType); return; case XmlTypeCode.Decimal: Init(another.decimalValue, xmlType); return; case XmlTypeCode.Double: Init(another.doubleValue, xmlType); return; case XmlTypeCode.Int: Init(another.intValue, xmlType); return; case XmlTypeCode.Long: Init(another.longValue, xmlType); return; case XmlTypeCode.Float: Init(another.floatValue, xmlType); return; case XmlTypeCode.String: Init(another.stringValue, xmlType); return; default: objectValue = another.objectValue; break; } } objectValue = value; schemaType = xmlType; }
// 3.2.4 Attribute Locally Valid and 3.4.4 private object AssessAttributeLocallyValid (XsAttribute attr, XmlSchemaInfo info, XmlValueGetter getter) { if (info != null) { info.SchemaAttribute = attr; info.SchemaType = attr.AttributeSchemaType; } // 2. - 4. if (attr.AttributeType == null) HandleError ("Attribute type is missing for " + attr.QualifiedName); XsDatatype dt = attr.AttributeType as XsDatatype; if (dt == null) dt = ((SimpleType) attr.AttributeType).Datatype; object parsedValue = null; // It is a bit heavy process, so let's omit as long as possible ;-) if (dt != SimpleType.AnySimpleType || attr.ValidatedFixedValue != null) { try { CurrentAttributeType = dt; parsedValue = getter (); } catch (Exception ex) { // It is inevitable and bad manner. HandleError (String.Format ("Attribute value is invalid against its data type {0}", dt != null ? dt.TokenizedType : default (XmlTokenizedType)), ex); } // check part of 3.14.4 StringValid SimpleType st = attr.AttributeSchemaType; if (st != null) { string xav = null; try { xav = new XmlAtomicValue (parsedValue, attr.AttributeSchemaType).Value; } catch (Exception ex) { HandleError (String.Format ("Failed to convert attribute value to type {0}", st.QualifiedName), ex); } if (xav != null) ValidateRestrictedSimpleTypeValue (st, ref dt, xav); } if (attr.ValidatedFixedValue != null) { if (!XmlSchemaUtil.AreSchemaDatatypeEqual (attr.AttributeSchemaType, attr.ValidatedFixedTypedValue, attr.AttributeSchemaType, parsedValue)) HandleError (String.Format ("The value of the attribute {0} does not match with its fixed value '{1}' in the space of type {2}", attr.QualifiedName, attr.ValidatedFixedValue, dt)); parsedValue = attr.ValidatedFixedTypedValue; } } #region ID Constraints if (!IgnoreIdentity) { string error = idManager.AssessEachAttributeIdentityConstraint (dt, parsedValue, ((QName) elementQNameStack [elementQNameStack.Count - 1]).Name); if (error != null) HandleError (error); } #endregion #region Key Constraints if (!IgnoreIdentity) ValidateKeyFieldsAttribute (attr, parsedValue); #endregion return parsedValue; }
//------------------------------------------------------------------------ // External type to external type //------------------------------------------------------------------------ internal static XmlAtomicValue ConvertToType(XmlAtomicValue value, XmlQueryType destinationType) { Debug.Assert(destinationType.IsStrict && destinationType.IsAtomicValue, "Can only convert to strict atomic type."); // This conversion matrix should match the one in XmlILVisitor.GetXsltConvertMethod switch (destinationType.TypeCode) { case XmlTypeCode.Boolean: switch (value.XmlType.TypeCode) { case XmlTypeCode.Boolean: case XmlTypeCode.Double: case XmlTypeCode.String: return new XmlAtomicValue(destinationType.SchemaType, ToBoolean(value)); } break; case XmlTypeCode.DateTime: if (value.XmlType.TypeCode == XmlTypeCode.String) return new XmlAtomicValue(destinationType.SchemaType, ToDateTime(value.Value)); break; case XmlTypeCode.Decimal: if (value.XmlType.TypeCode == XmlTypeCode.Double) return new XmlAtomicValue(destinationType.SchemaType, ToDecimal(value.ValueAsDouble)); break; case XmlTypeCode.Double: switch (value.XmlType.TypeCode) { case XmlTypeCode.Boolean: case XmlTypeCode.Double: case XmlTypeCode.String: return new XmlAtomicValue(destinationType.SchemaType, ToDouble(value)); case XmlTypeCode.Decimal: return new XmlAtomicValue(destinationType.SchemaType, ToDouble((decimal) value.ValueAs(DecimalType, null))); case XmlTypeCode.Int: case XmlTypeCode.Long: return new XmlAtomicValue(destinationType.SchemaType, ToDouble(value.ValueAsLong)); } break; case XmlTypeCode.Int: case XmlTypeCode.Long: if (value.XmlType.TypeCode == XmlTypeCode.Double) return new XmlAtomicValue(destinationType.SchemaType, ToLong(value.ValueAsDouble)); break; case XmlTypeCode.String: switch (value.XmlType.TypeCode) { case XmlTypeCode.Boolean: case XmlTypeCode.Double: case XmlTypeCode.String: return new XmlAtomicValue(destinationType.SchemaType, ToString(value)); case XmlTypeCode.DateTime: return new XmlAtomicValue(destinationType.SchemaType, ToString(value.ValueAsDateTime)); } break; } Debug.Fail("Conversion from " + value.XmlType.QualifiedName.Name + " to " + destinationType + " is not supported."); return value; }
/// <summary> /// Cache all or part of the attribute's typed value. /// </summary> public void Init(XmlAtomicValue value) { _text = null; _value = value; }
/// <summary> /// Cache all or part of the attribute's string value. /// </summary> public void Init(string text) { _text = text; _value = null; }
/// <summary> /// Fold a XsltConvert applied to a Literal into another Literal. If the fold results in some kind of /// conversion error, or if the QilExpression cannot represent the result as a Literal, return an unfolded /// XsltConvert expression. /// </summary> private QilNode FoldXsltConvert(QilNode ndLiteral, XmlQueryType typTarget) { try { if (typTarget.IsAtomicValue) { // Convert the literal to an XmlAtomicValue XmlAtomicValue value = new XmlAtomicValue(ndLiteral.XmlType.SchemaType, ExtractLiteralValue(ndLiteral)); value = XsltConvert.ConvertToType(value, typTarget); if (typTarget == TypeFactory.StringX) return this.f.LiteralString(value.Value); else if (typTarget == TypeFactory.IntX) return this.f.LiteralInt32(value.ValueAsInt); else if (typTarget == TypeFactory.IntegerX) return this.f.LiteralInt64(value.ValueAsLong); else if (typTarget == TypeFactory.DecimalX) return this.f.LiteralDecimal((decimal) value.ValueAs(XsltConvert.DecimalType)); else if (typTarget == TypeFactory.DoubleX) return this.f.LiteralDouble(value.ValueAsDouble); else if (typTarget == TypeFactory.BooleanX) return value.ValueAsBoolean ? this.f.True() : this.f.False(); } } catch (OverflowException) {} catch (FormatException) {} // Conversion error or QilExpression cannot represent resulting literal return this.f.XsltConvert(ndLiteral, typTarget); }
/// <summary> /// Cache all or part of the attribute's typed value. /// </summary> public void Init(XmlAtomicValue value) { this.text = null; this.value = value; }
/// <summary> /// Cache all or part of the attribute's string value. /// </summary> public void Init(string text) { this.text = text; this.value = null; }
private void Init(object value, XmlSchemaType xmlType) { if (value == null) { throw new ArgumentNullException("value"); } if (xmlType == null) { throw new ArgumentNullException("xmlType"); } switch (Type.GetTypeCode(value.GetType())) { case TypeCode.Boolean: this.Init((bool)value, xmlType); return; case TypeCode.Int16: case TypeCode.UInt16: case TypeCode.Int32: this.Init((int)value, xmlType); return; case TypeCode.UInt32: case TypeCode.Int64: this.Init((long)value, xmlType); return; case TypeCode.Single: this.Init((float)value, xmlType); return; case TypeCode.Double: this.Init((double)value, xmlType); return; case TypeCode.Decimal: this.Init((decimal)value, xmlType); return; case TypeCode.DateTime: this.Init((DateTime)value, xmlType); return; case TypeCode.String: this.Init((string)value, xmlType); return; } ICollection collection = value as ICollection; if (collection != null && collection.Count == 1) { if (collection is IList) { this.Init(((IList)collection)[0], xmlType); } else { IEnumerator enumerator = collection.GetEnumerator(); if (!enumerator.MoveNext()) { return; } if (enumerator.Current is DictionaryEntry) { DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current; this.Init(dictionaryEntry.Value, xmlType); } else { this.Init(enumerator.Current, xmlType); } } return; } XmlAtomicValue xmlAtomicValue = value as XmlAtomicValue; if (xmlAtomicValue != null) { XmlTypeCode xmlTypeCode = xmlAtomicValue.xmlTypeCode; switch (xmlTypeCode) { case XmlTypeCode.String: this.Init(xmlAtomicValue.stringValue, xmlType); return; case XmlTypeCode.Boolean: this.Init(xmlAtomicValue.booleanValue, xmlType); return; case XmlTypeCode.Decimal: this.Init(xmlAtomicValue.decimalValue, xmlType); return; case XmlTypeCode.Float: this.Init(xmlAtomicValue.floatValue, xmlType); return; case XmlTypeCode.Double: this.Init(xmlAtomicValue.doubleValue, xmlType); return; default: if (xmlTypeCode == XmlTypeCode.Long) { this.Init(xmlAtomicValue.longValue, xmlType); return; } if (xmlTypeCode == XmlTypeCode.Int) { this.Init(xmlAtomicValue.intValue, xmlType); return; } this.objectValue = xmlAtomicValue.objectValue; break; case XmlTypeCode.DateTime: this.Init(xmlAtomicValue.dateTimeValue, xmlType); return; } } this.objectValue = value; this.schemaType = xmlType; }