private SchemaElementDecl CheckXsiTypeAndNil(SchemaElementDecl elementDecl, string xsiType, string xsiNil, ref bool declFound)
{
XmlQualifiedName xsiTypeName = XmlQualifiedName.Empty;
if (xsiType != null)
{
object typedVal = null;
Exception exception = s_dtQName.TryParseValue(xsiType, _nameTable, _nsResolver, out typedVal);
if (exception != null)
{
SendValidationEvent(SR.Sch_InvalidValueDetailedAttribute, new string[] { "type", xsiType, s_dtQName.TypeCodeString, exception.Message }, exception);
}
else
{
xsiTypeName = typedVal as XmlQualifiedName;
}
}
if (elementDecl != null)
{ //nillable is not dependent on xsi:type.
if (elementDecl.IsNillable)
{
if (xsiNil != null)
{
_context.IsNill = XmlConvert.ToBoolean(xsiNil);
if (_context.IsNill && elementDecl.Presence == SchemaDeclBase.Use.Fixed)
{
Debug.Assert(elementDecl.DefaultValueTyped != null);
SendValidationEvent(SR.Sch_XsiNilAndFixed);
}
}
}
else if (xsiNil != null)
{
SendValidationEvent(SR.Sch_InvalidXsiNill);
}
}
if (xsiTypeName.IsEmpty)
{
if (elementDecl != null && elementDecl.IsAbstract)
{
SendValidationEvent(SR.Sch_AbstractElement, QNameString(_context.LocalName, _context.Namespace));
elementDecl = null;
}
}
else
{
SchemaElementDecl elementDeclXsi = _compiledSchemaInfo.GetTypeDecl(xsiTypeName);
XmlSeverityType severity = XmlSeverityType.Warning;
if (HasSchema && _processContents == XmlSchemaContentProcessing.Strict)
{
severity = XmlSeverityType.Error;
}
if (elementDeclXsi == null && xsiTypeName.Namespace == _nsXs)
{
XmlSchemaType schemaType = DatatypeImplementation.GetSimpleTypeFromXsdType(xsiTypeName);
if (schemaType == null)
{ //try getting complexType - xs:anyType
schemaType = XmlSchemaType.GetBuiltInComplexType(xsiTypeName);
}
if (schemaType != null)
{
elementDeclXsi = schemaType.ElementDecl;
}
}
if (elementDeclXsi == null)
{
SendValidationEvent(SR.Sch_XsiTypeNotFound, xsiTypeName.ToString(), severity);
elementDecl = null;
}
else
{
declFound = true;
if (elementDeclXsi.IsAbstract)
{
SendValidationEvent(SR.Sch_XsiTypeAbstract, xsiTypeName.ToString(), severity);
elementDecl = null;
}
else if (elementDecl != null && !XmlSchemaType.IsDerivedFrom(elementDeclXsi.SchemaType, elementDecl.SchemaType, elementDecl.Block))
{
SendValidationEvent(SR.Sch_XsiTypeBlockedEx, new string[] { xsiTypeName.ToString(), QNameString(_context.LocalName, _context.Namespace) });
elementDecl = null;
}
else
{
if (elementDecl != null)
{ //Get all element decl properties before assigning xsi:type decl; nillable already checked
elementDeclXsi = elementDeclXsi.Clone(); //Before updating properties onto xsi:type decl, clone it
elementDeclXsi.Constraints = elementDecl.Constraints;
elementDeclXsi.DefaultValueRaw = elementDecl.DefaultValueRaw;
elementDeclXsi.DefaultValueTyped = elementDecl.DefaultValueTyped;
elementDeclXsi.Block = elementDecl.Block;
}
_context.ElementDeclBeforeXsi = elementDecl;
elementDecl = elementDeclXsi;
}
}
}
return elementDecl;
}