internal void HandleElementColumn(XmlSchemaElement elem, DataTable table, bool isBase){
Type type = null;
XmlSchemaElement el = elem.Name != null ? elem : (XmlSchemaElement) elementsTable[elem.RefName];
if (el == null) // it's possible due to some XSD compiler optimizations
return; // do nothing
XmlSchemaAnnotated typeNode = FindTypeNode(el);
String strType = null;
SimpleType xsdType = null;
if (typeNode == null) {
strType = el.SchemaTypeName.Name;
if (Common.ADP.IsEmpty(strType)) {
strType = "";
type = typeof(string);
}
else {
type = ParseDataType(el.SchemaTypeName.Name);
}
}
else if (typeNode is XmlSchemaSimpleType) {
//
XmlSchemaSimpleType simpleTypeNode = typeNode as XmlSchemaSimpleType;
xsdType = new SimpleType(simpleTypeNode);
// ((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 check is for annonymos simple type,
// it should be user defined Named simple type
if (((XmlSchemaSimpleType)typeNode).Name != null && ((XmlSchemaSimpleType)typeNode).Name.Length != 0 && ((XmlSchemaSimpleType)typeNode).QualifiedName.Namespace != Keywords.XSDNS) {
string targetNamespace = XSDSchema.GetMsdataAttribute(typeNode, Keywords.TARGETNAMESPACE);
strType = ((XmlSchemaSimpleType)typeNode).QualifiedName.ToString(); // use qualifed name
type = ParseDataType(strType);
}
else {
simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS) ?
schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
null;
while (simpleTypeNode != null) {
xsdType.LoadTypeValues(simpleTypeNode);
simpleTypeNode = (xsdType.XmlBaseType!= null && xsdType.XmlBaseType.Namespace != Keywords.XSDNS) ?
schemaTypes[xsdType.XmlBaseType] as XmlSchemaSimpleType :
null;
}
type = ParseDataType(xsdType.BaseType);
strType = xsdType.Name;
if(xsdType.Length == 1 && type == typeof(string)) {
type = typeof(Char);
}
}
}
else if (typeNode is XmlSchemaElement) { // theoratically no named simpletype should come here
strType = ((XmlSchemaElement)typeNode).SchemaTypeName.Name;
type = ParseDataType(strType);
}
else if (typeNode is XmlSchemaComplexType) {
if (ADP.IsEmpty(XSDSchema.GetMsdataAttribute(elem, Keywords.MSD_DATATYPE))) {
throw ExceptionBuilder.DatatypeNotDefined();
}
else {
type = typeof(object);
}
}
else {
if (typeNode.Id == null)
throw ExceptionBuilder.DatatypeNotDefined();
else
throw ExceptionBuilder.UndefinedDatatype(typeNode.Id);
}
DataColumn column;
string columnName = XmlConvert.DecodeName(GetInstanceName(el));
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
if (column.ColumnMapping != MappingType.Element)
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 ((Common.ADP.IsEmpty(elem.QualifiedName.Namespace) && Common.ADP.IsEmpty(column._columnUri)) || // backward compatability :SQL BU DT 310912
(string.Compare(elem.QualifiedName.Namespace, column.Namespace, StringComparison.Ordinal) == 0))
{
return; // backward compatability
}
column = new DataColumn(columnName, type, null, MappingType.Element);// 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.Element);
}
SetProperties(column, el.UnhandledAttributes);
HandleColumnExpression(column, el.UnhandledAttributes);
SetExtProperties(column, el.UnhandledAttributes);
if (!Common.ADP.IsEmpty(column.Expression)) {
ColumnExpressions.Add(column);
}
// Update XSD type to point to simple types actual namespace instead of normalized default namespace in case of remoting
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 = this.FromInference ||(elem.MinOccurs == 0 ) || elem.IsNillable;
if (!elem.RefName.IsEmpty || elem.QualifiedName.Namespace != table.Namespace)
{ // if ref element (or in diferent NS) it is global element, so form MUST BE Qualified
column.Namespace = elem.QualifiedName.Namespace;
column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
}
else { // it is local, hence check for 'form' on local element, if not specified, check for 'elemenfformdefault' on schema element
if (elem.Form == XmlSchemaForm.Unqualified) {
column.Namespace = String.Empty;
}
else if (elem.Form == XmlSchemaForm.None) {
XmlSchemaObject e = (XmlSchemaObject)elem.Parent;
while (e.Parent != null) {
e = e.Parent;
}
if (((XmlSchema)e).ElementFormDefault == XmlSchemaForm.Unqualified) {
column.Namespace = String.Empty;
}
}
else {
column.Namespace = elem.QualifiedName.Namespace;
column.Namespace = GetStringAttribute(el, "targetNamespace", column.Namespace);
}
}
String tmp = GetStringAttribute(elem, Keywords.MSD_ORDINAL, (-1).ToString(CultureInfo.CurrentCulture));
int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
if(isToAdd) {
if(ordinal>-1 && ordinal<table.Columns.Count)
table.Columns.AddAt(ordinal, column);
else
table.Columns.Add(column);
}
if (column.Namespace == table.Namespace)
column._columnUri = null; // to not raise a column change namespace again
if(this.FromInference) {// search for prefix after adding to table, so NS has its final value, and
column.Prefix = GetPrefix(column.Namespace); // it can inherit its NS from DataTable, if it is null
}
string strDefault = el.DefaultValue;
if (strDefault != null )
try {
column.DefaultValue = column.ConvertXmlToObject(strDefault);
}
catch (System.FormatException) {
throw ExceptionBuilder.CannotConvert(strDefault, type.FullName);
}
}