internal void HandleAttributeColumn(XmlSchemaAttribute attrib, DataTable table, bool isBase)
{
Type type = null;
XmlSchemaAttribute attr = attrib.Name != null ? attrib : (XmlSchemaAttribute)_attributes[attrib.RefName];
XmlSchemaAnnotated typeNode = FindTypeNode(attr);
string strType = null;
SimpleType xsdType = null;
if (typeNode == null)
{
strType = attr.SchemaTypeName.Name;
if (string.IsNullOrEmpty(strType))
{
strType = string.Empty;
type = typeof(string);
}
else
{
if (attr.SchemaTypeName.Namespace != Keywords.XSDNS) // it is UD Simple Type, can it be?
type = ParseDataType(attr.SchemaTypeName.ToString());
else
type = ParseDataType(attr.SchemaTypeName.Name);
}
}
else if (typeNode is XmlSchemaSimpleType)
{
XmlSchemaSimpleType node = typeNode as XmlSchemaSimpleType;
xsdType = new SimpleType(node);
if (node.QualifiedName.Name != null && node.QualifiedName.Name.Length != 0 && node.QualifiedName.Namespace != Keywords.XSDNS)
{
// this means UDSimpleType
strType = node.QualifiedName.ToString(); // use qualifed name
type = ParseDataType(node.QualifiedName.ToString());// search with QName
}
else
{
type = ParseDataType(xsdType.BaseType);
strType = xsdType.Name;
if (xsdType.Length == 1 && type == typeof(string))
{
type = typeof(char);
}
}
}
else if (typeNode is XmlSchemaElement)
{
strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
type = ParseDataType(strType);
}
else
{
if (typeNode.Id == null)
throw ExceptionBuilder.DatatypeNotDefined();
else
throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
}
DataColumn column;
string columnName = XmlConvert.DecodeName(GetInstanceName(attr));
bool isToAdd = true;
if ((!isBase || FromInference) && (table.Columns.Contains(columnName, true)))
{
column = table.Columns[columnName];
isToAdd = false;
if (FromInference)
{ // for backward compatability with old inference
// throw eception if same column is being aded with different mapping
if (column.ColumnMapping != MappingType.Attribute)
throw ExceptionBuilder.ColumnTypeConflict(column.ColumnName);
// in previous inference , if we have incoming column with different NS, we think as different column and
//while adding , since there is no NS concept for datacolumn, we used to throw exception
// simulate the same behavior.
if ((string.IsNullOrEmpty(attrib.QualifiedName.Namespace) && string.IsNullOrEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
(string.Equals(attrib.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal)))
{
return; // backward compatability
}
column = new DataColumn(columnName, type, null, MappingType.Attribute); // this is to fix issue with Exception we used to throw for old inference engine if column
//exists with different namespace; while adding it to columncollection
isToAdd = true;
}
}
else
{
column = new DataColumn(columnName, type, null, MappingType.Attribute);
}
SetProperties(column, attr.UnhandledAttributes);
HandleColumnExpression(column, attr.UnhandledAttributes);
SetExtProperties(column, attr.UnhandledAttributes);
if ((column.Expression != null) && (column.Expression.Length != 0))
{
_columnExpressions.Add(column);
}
if (xsdType != null && xsdType.Name != null && xsdType.Name.Length > 0)
{
if (XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE) != null)
{
column.XmlDataType = xsdType.SimpleTypeQualifiedName;
}
}
else
{
column.XmlDataType = strType;
}
column.SimpleType = xsdType;
column.AllowDBNull = !(attrib.Use == XmlSchemaUse.Required);
column.Namespace = attrib.QualifiedName.Namespace;
column.Namespace = GetStringAttribute(attrib, "targetNamespace", column.Namespace);
if (isToAdd)
{
if (FromInference)
{ // move this setting to SetProperties
column.AllowDBNull = true;
column.Prefix = GetPrefix(column.Namespace);
}
table.Columns.Add(column);
}
if (attrib.Use == XmlSchemaUse.Prohibited)
{
column.ColumnMapping = MappingType.Hidden;
column.AllowDBNull = GetBooleanAttribute(attr, Keywords.MSD_ALLOWDBNULL, true);
string defValue = GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE);
if (defValue != null)
try
{
column.DefaultValue = column.ConvertXmlToObject(defValue);
}
catch (System.FormatException)
{
throw ExceptionBuilder.CannotConvert(defValue, type.FullName);
}
}
// XDR March change
string strDefault = (attrib.Use == XmlSchemaUse.Required) ? GetMsdataAttribute(attr, Keywords.MSD_DEFAULTVALUE) : attr.DefaultValue;
if ((attr.Use == XmlSchemaUse.Optional) && (strDefault == null))
strDefault = attr.FixedValue;
if (strDefault != null)
try
{
column.DefaultValue = column.ConvertXmlToObject(strDefault);
}
catch (System.FormatException)
{
throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
}
}