XMLSchema.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / Data / System / Data / XMLSchema.cs / 2 / XMLSchema.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data {
    using System; 
    using System.Data.Common;
    using System.Xml;
    using System.Xml.Schema;
    using System.Diagnostics; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Globalization; 
    using System.ComponentModel;
    using System.Security; 
    using System.Security.Permissions;

    internal class XMLSchema {
 
        internal static TypeConverter GetConverter(Type type) {
            HostProtectionAttribute protAttrib = new HostProtectionAttribute(); 
            protAttrib.SharedState = true; 

            CodeAccessPermission permission = (CodeAccessPermission)protAttrib.CreatePermission(); 
            permission.Assert();
            try {
                return TypeDescriptor.GetConverter(type);
            } 
            finally {
                CodeAccessPermission.RevertAssert(); 
            } 
        }
 
        internal static void SetProperties(Object instance, XmlAttributeCollection attrs) {
            // This is called from both XSD and XDR schemas.
            // Do we realy need it in XSD ???
            for (int i = 0; i < attrs.Count; i++) { 
                if (attrs[i].NamespaceURI == Keywords.MSDNS) {
                    string name  = attrs[i].LocalName; 
                    string value = attrs[i].Value; 

                    if (name == "DefaultValue" || name == "RemotingFormat") 
                        continue;
// Webdata 97925, skipp expressions, we will handle them after SetProperties (in xdrschema)
                    if (name == "Expression" &&  instance is DataColumn)
                        continue; 

                    PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name]; 
                    if (pd != null) { 
                        // Standard property
                        Type type = pd.PropertyType; 

                        TypeConverter converter = XMLSchema.GetConverter(type);
                        object propValue;
                        if (converter.CanConvertFrom(typeof(string))) { 
                            propValue = converter.ConvertFromString(value);
                        }else if (type == typeof(Type)) { 
                            propValue = Type.GetType(value); 
                        }else if (type == typeof(CultureInfo)) {
                            propValue = new CultureInfo(value); 
                        }else {
                            throw ExceptionBuilder.CannotConvert(value,type.FullName);
                        }
                        pd.SetValue(instance, propValue); 
                    }
                } 
            } 
        }// SetProperties
 
        internal static bool FEqualIdentity(XmlNode node, String name, String ns) {
            if (node != null && node.LocalName == name && node.NamespaceURI == ns)
                return true;
 
            return false;
        } 
 
        internal static bool GetBooleanAttribute(XmlElement element, String attrName, String attrNS, bool defVal) {
            string value = element.GetAttribute(attrName, attrNS); 
            if (value == null || value.Length == 0) {
                return defVal;
            }
            if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){ 
                return true;
            } 
            if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){ 
                return false;
            } 
            // Error processing:
            throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
        }
 
        internal static string GenUniqueColumnName(string proposedName, DataTable table) {
 
            if (table.Columns.IndexOf(proposedName) >= 0) { 
                for (int i=0; i <= table.Columns.Count; i++) {
                    string tempName = proposedName + "_" + (i).ToString(CultureInfo.InvariantCulture); 
                    if (table.Columns.IndexOf(tempName) >= 0) {
                        continue;
                    }
                    else { 
                        return tempName;
                    } 
                } 
            }
            return proposedName; 
        }
     }

    internal sealed class ConstraintTable { 
        public DataTable table;
        public XmlSchemaIdentityConstraint constraint; 
        public ConstraintTable(DataTable t, XmlSchemaIdentityConstraint c) { 
            table = t;
            constraint = c; 
        }
    }

    internal sealed class XSDSchema :  XMLSchema 
    {
        XmlSchemaSet _schemaSet = null; 
        XmlSchemaElement dsElement = null; 
        DataSet _ds = null;
        String _schemaName = null; 
        private ArrayList ColumnExpressions;
        private Hashtable ConstraintNodes;
        private ArrayList RefTables;
        private ArrayList complexTypes; 
        XmlSchemaObjectCollection annotations;
        XmlSchemaObjectCollection elements; 
        Hashtable attributes; 
        Hashtable elementsTable;
        Hashtable attributeGroups; 
        Hashtable schemaTypes;
        Hashtable expressions;
        Dictionary > tableDictionary;
 
        Hashtable udSimpleTypes;
 
        Hashtable existingSimpleTypeMap; 

        private bool fromInference = false; 

        internal bool FromInference {
            get {
                return fromInference; 
            }
            set { 
                fromInference = value; 
            }
        } 

        private void CollectElementsAnnotations(XmlSchema schema){
            ArrayList schemaList = new ArrayList();
            CollectElementsAnnotations(schema, schemaList); 
            schemaList.Clear();
        } 
 
        private void CollectElementsAnnotations(XmlSchema schema, ArrayList schemaList){
            if (schemaList.Contains(schema)) { 
                return;
            }
            schemaList.Add(schema);
 
            foreach(object item in schema.Items) {
                if (item is XmlSchemaAnnotation) { 
                    annotations.Add((XmlSchemaAnnotation)item); 
                }
                if (item is XmlSchemaElement) { 
                    XmlSchemaElement elem = (XmlSchemaElement)item;
                    elements.Add(elem);
                    elementsTable[elem.QualifiedName] = elem;
                } 
                if (item is XmlSchemaAttribute) {
                    XmlSchemaAttribute attr = (XmlSchemaAttribute)item; 
                    attributes[attr.QualifiedName] = attr; 
                }
                if (item is XmlSchemaAttributeGroup) { 
                    XmlSchemaAttributeGroup attr = (XmlSchemaAttributeGroup)item;
                    attributeGroups[attr.QualifiedName] = attr;
                }
                if (item is XmlSchemaType) { 
                    string MSDATATargetNamespace = null;
                    if (item is XmlSchemaSimpleType) { 
                        MSDATATargetNamespace = XSDSchema.GetMsdataAttribute((XmlSchemaType)item, Keywords.TARGETNAMESPACE); 
                    }
 
                    XmlSchemaType type = (XmlSchemaType)item;
                    schemaTypes[type.QualifiedName] = type;

// Webdata 92054 if we have a User Defined simple type, cache it so later we may need for mapping 
// meanwhile more convinient solution would be to directly use schemaTypes, but it would be more complex to handle
                    XmlSchemaSimpleType xmlSimpleType = (item as XmlSchemaSimpleType ); 
                    if (xmlSimpleType != null) { 
                        if (udSimpleTypes == null) {
                            udSimpleTypes = new Hashtable(); 
                        }

                        udSimpleTypes[type.QualifiedName.ToString()] = xmlSimpleType;
                        DataColumn dc = (DataColumn)existingSimpleTypeMap[type.QualifiedName.ToString()]; 
                        // Assumption is that our simple type qualified name ihas the same output as XmlSchemaSimpleType type.QualifiedName.ToString()
                        SimpleType tmpSimpleType = (dc != null)? dc.SimpleType: null; 
// 
                        if (tmpSimpleType != null) {
                            SimpleType tmpDataSimpleType = new SimpleType(xmlSimpleType); 
                            string errorStr = tmpSimpleType.HasConflictingDefinition(tmpDataSimpleType);
                            if (errorStr.Length != 0) {
                                throw ExceptionBuilder.InvalidDuplicateNamedSimpleTypeDelaration(tmpDataSimpleType.SimpleTypeQualifiedName, errorStr);
                            } 
                        }
 
                    } 
                }
            } 
            foreach(XmlSchemaExternal include in schema.Includes) {
                if (include is XmlSchemaImport)
                    continue;
                if (include.Schema != null) { 
                    CollectElementsAnnotations(include.Schema, schemaList);
                } 
            } 
        }
 
        internal static string QualifiedName(string name) {
            int iStart = name.IndexOf(':');
            if (iStart == -1)
                return Keywords.XSD_PREFIXCOLON + name; 
            else
                return name; 
        } 

        internal static void SetProperties(Object instance, XmlAttribute[] attrs) { 
            // This is called from both XSD and XDR schemas.
            // Do we realy need it in XSD ???
            if (attrs == null)
                return; 
            for (int i = 0; i < attrs.Length; i++) {
                if (attrs[i].NamespaceURI == Keywords.MSDNS) { 
                    string name  = attrs[i].LocalName; 
                    string value = attrs[i].Value;
 
                    if (name == "DefaultValue" || name == "Ordinal" || name == "Locale" || name == "RemotingFormat")
                        continue;

                    if (name == "Expression" &&  instance is DataColumn) // Webdata 97925: we will handle columnexpressions at HandleColumnExpression 
                        continue;
 
                    if (name == "DataType") { 
                        DataColumn col = instance as DataColumn;
                        if (col != null) { 
                            Type dataType = Type.GetType(value);
                            col.DataType = dataType;
                        }
 
                        continue;
                    } 
 
                    PropertyDescriptor pd = TypeDescriptor.GetProperties(instance)[name];
                    if (pd != null) { 
                        // Standard property
                        Type type = pd.PropertyType;

                        TypeConverter converter = XMLSchema.GetConverter(type); 
                        object propValue;
                        if (converter.CanConvertFrom(typeof(string))) { 
                            propValue = converter.ConvertFromString(value); 
                        }else if (type == typeof(Type)) {
                            propValue = Type.GetType(value); 
                        }else if (type == typeof(CultureInfo)) {
                            propValue = new CultureInfo(value);
                        }else {
                            throw ExceptionBuilder.CannotConvert(value,type.FullName); 
                        }
                        pd.SetValue(instance, propValue); 
                    } 
                }
            } 
        }// SetProperties

        private static void SetExtProperties(Object instance, XmlAttribute[] attrs) {
            PropertyCollection props = null; 
            if (attrs == null)
                return; 
            for (int i = 0; i < attrs.Length; i++) { 
                if (attrs[i].NamespaceURI == Keywords.MSPROPNS) {
                    if(props == null) { 
                        object val = TypeDescriptor.GetProperties(instance)["ExtendedProperties"].GetValue(instance);
                        Debug.Assert(val is PropertyCollection, "We can set values only for classes that have ExtendedProperties");
                        props = (PropertyCollection) val;
                    } 
                    string propName = XmlConvert.DecodeName(attrs[i].LocalName);
 
                    if (instance is ForeignKeyConstraint) { 
                        if (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal))
                            propName = propName.Substring(3); 
                        else
                            continue;
                    }
                    if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_REL_PREFIX, StringComparison.Ordinal))) { 
                            propName = propName.Substring(4);
                    } 
                    else if ((instance is DataRelation) && (propName.StartsWith(Keywords.MSD_FK_PREFIX, StringComparison.Ordinal))) { 
                        continue;
                    } 

                    props.Add(propName, attrs[i].Value);
                }
            } 
        }// SetExtProperties
 
        private void HandleColumnExpression(Object instance, XmlAttribute[] attrs) { 
            if (attrs == null)
                return; 
            DataColumn dc = instance as DataColumn;
            Debug.Assert(dc != null, "HandleColumnExpression is supposed to be called for DataColumn");
            if (dc != null ) {
                for (int i = 0; i < attrs.Length; i++) { 
                    if (attrs[i].NamespaceURI == Keywords.MSDNS) {
                        if (attrs[i].LocalName == "Expression"){ 
                            if (this.expressions == null) 
                                this.expressions = new Hashtable();
                            this.expressions[dc] = attrs[i].Value; 
                            ColumnExpressions.Add(dc);
                            break;
                        }
                    } 
                }
            } 
        } 

        internal static String GetMsdataAttribute(XmlSchemaAnnotated node, String ln) { 
            XmlAttribute[]   nodeAttributes = node.UnhandledAttributes;
            if (nodeAttributes!=null)
                for(int i=0; i Decimal.One && (((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) // we know frominference condition 
                        ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
 
            if (((XmlSchemaElement)el).RefName.Name.Length != 0) {
                if (!FromInference || (((XmlSchemaElement)el).MaxOccurs != Decimal.One &&  !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)))
                    continue;
            } 

 
                    if (!IsTable ((XmlSchemaElement)el)) 
                        return false;
 
                    continue;
                }

                if (el is XmlSchemaParticle) { 
                    if (!IsDatasetParticle((XmlSchemaParticle)el))
                        return false; 
                } 
            }
 
            return true;
        }

        private int DatasetElementCount(XmlSchemaObjectCollection elements) { 
            int nCount = 0;
            foreach(XmlSchemaElement XmlElement in elements) { 
                if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET,  /*default:*/ false)) { 
                    nCount++;
                } 
            }
            return nCount;
        }
 
        private XmlSchemaElement FindDatasetElement(XmlSchemaObjectCollection elements) {
            foreach(XmlSchemaElement XmlElement in elements) { 
                if (GetBooleanAttribute(XmlElement, Keywords.MSD_ISDATASET,  /*default:*/ false)) 
                    return XmlElement;
            } 
            if ((elements.Count == 1) || (this.FromInference && elements.Count > 0)) { //let's see if this element looks like a DataSet

                XmlSchemaElement node = (XmlSchemaElement)elements[0];
                if (!GetBooleanAttribute(node, Keywords.MSD_ISDATASET,  /*default:*/ true)) 
                    return null;
 
                XmlSchemaComplexType ct = node.SchemaType as XmlSchemaComplexType; 
                if (ct == null)
                    return null; 

                while (ct != null) {
                    if (HasAttributes(ct.Attributes))
                        return null; 

                     if (ct.ContentModel is XmlSchemaSimpleContent){ 
                         XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content; 
                         if (cContent is XmlSchemaSimpleContentExtension) {
                              XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent ); 
                             if (HasAttributes(ccExtension.Attributes))
                                return null;
                          } else {
                              XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent ); 
                             if (HasAttributes(ccRestriction.Attributes))
                                return null; 
                          } 
                     }
 

                    XmlSchemaParticle particle = GetParticle(ct);
                    if (particle != null) {
                        if (!IsDatasetParticle(particle)) 
                            return null; // it's a table
                        } 
 
                    if (ct.BaseXmlSchemaType is XmlSchemaComplexType)
                        ct = (XmlSchemaComplexType)ct.BaseXmlSchemaType; 
                    else
                        break;
                }
 

                //if we are here there all elements are tables 
                return node; 
            }
            return null; 
        }

        public void LoadSchema(XmlSchemaSet schemaSet , DataTable dt) {
            if (dt.DataSet != null) 
                LoadSchema(schemaSet, dt.DataSet);
        } 
        public void LoadSchema(XmlSchemaSet schemaSet , DataSet ds) { //Element schemaRoot, DataSet ds) { 
            ConstraintNodes = new Hashtable();
            RefTables = new ArrayList(); 
            ColumnExpressions = new ArrayList();
            complexTypes = new ArrayList();
            bool setRootNStoDataSet = false;
            bool newDataSet = (ds.Tables.Count == 0); 

            if (schemaSet == null) // 
                return; 
            _schemaSet = schemaSet;
            _ds = ds; 
            ds.fIsSchemaLoading = true;

            foreach (XmlSchema schemaRoot in schemaSet.Schemas()) {
                _schemaName = schemaRoot.Id; 

                if (_schemaName == null ||_schemaName.Length == 0) { 
                    _schemaName = "NewDataSet"; 
                }
                ds.DataSetName = XmlConvert.DecodeName(_schemaName); 
                string ns = schemaRoot.TargetNamespace;
                if (ds.namespaceURI == null || ds.namespaceURI.Length == 0) {// set just one time, for backward compatibility
                    ds.namespaceURI = (ns== null)? string.Empty : ns;           // see fx\Data\XDO\ReadXml\SchemaM2.xml for more info
                } 
                break; // we just need to take Name and NS from first schema [V1.0 & v1.1 semantics]
            } 
 
            annotations = new XmlSchemaObjectCollection();
            elements = new XmlSchemaObjectCollection(); 
            elementsTable = new Hashtable();
            attributes = new Hashtable();
            attributeGroups = new Hashtable();
            schemaTypes = new Hashtable(); 
            tableDictionary = new Dictionary >() ;
 
            existingSimpleTypeMap = new Hashtable(); 
            foreach(DataTable dt in ds.Tables){
                foreach(DataColumn dc in dt.Columns) { 
                    if (dc.SimpleType!= null && dc.SimpleType.Name != null && dc.SimpleType.Name.Length != 0) {
                        existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc;
//                        existingSimpleTypeMap[dc.SimpleType.SimpleTypeQualifiedName] = dc.SimpleType;
                    } 
                }
            } 
 

 
            foreach (XmlSchema schemaRoot in schemaSet.Schemas())
                CollectElementsAnnotations(schemaRoot);

 

            dsElement = FindDatasetElement(elements); 
            if (dsElement != null) { 
                string mainName = GetStringAttribute (dsElement, Keywords.MSD_MAINDATATABLE, "");
                if (null != mainName) { 
                    ds.MainTableName = XmlConvert.DecodeName (mainName);
                }
            }
            else { 
                if (this.FromInference) {
                    ds.fTopLevelTable = true; // Backward compatability: for inference, if we do not read DataSet element 
                } 
                // we should not write it also
                setRootNStoDataSet = true; 
                //incase of Root is not mapped to DataSet and is mapped to DataTable instead; to be backward compatable
                // we need to set the Namespace of Root to DataSet's namespace also(it would be NS of First DataTable in collection)
            }
 
            List qnames = new List();
 
            if (ds != null && ds.UseDataSetSchemaOnly) { 
                int dataSetElementCount = DatasetElementCount(elements);
                if (dataSetElementCount == 0) { 
                    throw ExceptionBuilder.IsDataSetAttributeMissingInSchema();
                }
                else if (dataSetElementCount > 1) {
                    throw ExceptionBuilder.TooManyIsDataSetAtributeInSchema(); 
                }
 
                XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(dsElement); 
                if (ct.Particle != null) {
                    XmlSchemaObjectCollection items = GetParticleItems(ct.Particle); 
                    if (items != null) {
                        foreach (XmlSchemaAnnotated el in items){
                            XmlSchemaElement sel = el as XmlSchemaElement;
                            if (null != sel) { 
                                if(sel.RefName.Name.Length != 0 ) {
                                    qnames.Add(sel.QualifiedName); 
                                } 
                            }
                        } 
                    }
                }

            } 

            // Walk all the top level Element tags. 
            foreach (XmlSchemaElement element in elements) { 
                if (element == dsElement)
                    continue; 
                if (ds != null && ds.UseDataSetSchemaOnly && dsElement != null) {
                    if (dsElement.Parent != element.Parent) {
                        if (!qnames.Contains(element.QualifiedName)) {
                            continue; 
                        }
                    } 
                } 

                String typeName = GetInstanceName(element); 
                if (RefTables.Contains(element.QualifiedName.Namespace +":"+ typeName)) {
                    HandleRefTableProperties(RefTables, element);
                    continue;
                } 

                DataTable table = HandleTable(element); 
            } 

            if (dsElement!=null) 
                HandleDataSet(dsElement, newDataSet);

            foreach (XmlSchemaAnnotation annotation in annotations) {
                HandleRelations(annotation, false); 
            }
 
//just add Expressions, at this point and if ColumnExpressions.Count > 0, this.expressions should not be null 
            for(int i=0; i 0) { // if there is table, take first one's NS 
                    ds.Namespace = ds.Tables[0].Namespace;
                    ds.Prefix = ds.Tables[0].Prefix; 
                } 
                else {// otherwise, take TargetNS from first schema
                    Debug.Assert(schemaSet.Count == 1, "there should be one schema"); 
                    foreach (XmlSchema schemaRoot in schemaSet.Schemas()) { // we should have 1 schema
                        ds.Namespace = schemaRoot.TargetNamespace;
                    }
                } 
            }
        } 
 
        private void HandleRelations(XmlSchemaAnnotation ann, bool fNested) {
            foreach (object __items in ann.Items) 
            if (__items is XmlSchemaAppInfo) {
                XmlNode[] relations = ((XmlSchemaAppInfo) __items).Markup;
                for (int i = 0; i Decimal.One && (el.SchemaType is XmlSchemaComplexType)) 
                        ((XmlSchemaElement)el).MaxOccurs = pt.MaxOccurs;
 
 
                    DataTable child = null;
                    // to decide if element is our table, we ned to match both name and ns 
                    // 286043 - SQL BU Defect Tracking
                    if (((el.Name == null) && (el.RefName.Name == table.EncodedTableName && el.RefName.Namespace == table.Namespace)) ||
                        (IsTable(el) && el.Name == table.TableName)) {
                        if (this.FromInference) { 
                            child = HandleTable ((XmlSchemaElement)el);
                            Debug.Assert(child == table, "table not the same"); 
                        } 
                        else {
                            child = table; 
                        }
                    }
                    else {
                        child = HandleTable ((XmlSchemaElement)el); 
                        if (child == null && this.FromInference && el.Name == table.TableName) {
                            child = table; 
                        } 
                    }
 
                    if (child==null) {
                        if (!this.FromInference || el.Name != table.TableName) {// check is required to support 1.1 inference behavior
                            HandleElementColumn((XmlSchemaElement)el, table, isBase);
                        } 
                    }
                    else { 
                        DataRelation relation = null; 
                        if (el.Annotation != null)
                            HandleRelations(el.Annotation, true); 

                        DataRelationCollection childRelations = table.ChildRelations;
                        for (int j = 0; j < childRelations.Count; j++) {
                            if (!childRelations[j].Nested) 
                                continue;
 
                            if (child == childRelations[j].ChildTable) 
                                relation = childRelations[j];
                        } 

                        if (relation == null) {
                            tableChildren.Add(child);// how about prefix for this?
                            if(this.FromInference && table.UKColumnPositionForInference == -1) { // this is done for Inference 
                                int ukColumnPosition = -1;
                                foreach(DataColumn dc in table.Columns) { 
                                    if (dc.ColumnMapping == MappingType.Element) 
                                        ukColumnPosition++;
                                } 
                                table.UKColumnPositionForInference = ukColumnPosition + 1; // since it starts from
                            }
                        }
                    } 
                }
                else { 
                    HandleParticle((XmlSchemaParticle)item, table, tableChildren, isBase); 
                }
 
            }
            return ;
        }
 
        internal void HandleAttributes(XmlSchemaObjectCollection attributes, DataTable table, bool isBase) {
        foreach (XmlSchemaObject so in attributes) { 
                if (so is XmlSchemaAttribute) { 
                    HandleAttributeColumn((XmlSchemaAttribute) so, table, isBase);
                } 
                else {  // XmlSchemaAttributeGroupRef
                    XmlSchemaAttributeGroupRef groupRef =  so as XmlSchemaAttributeGroupRef;
                    XmlSchemaAttributeGroup schemaGroup = attributeGroups[groupRef.RefName] as XmlSchemaAttributeGroup;
                    if (schemaGroup!=null) { 
                        HandleAttributeGroup(schemaGroup, table, isBase);
                    } 
                } 
            }
        } 

       private void HandleAttributeGroup(XmlSchemaAttributeGroup attributeGroup, DataTable table, bool isBase) {
           foreach (XmlSchemaObject obj in attributeGroup.Attributes) {
               if (obj is XmlSchemaAttribute) { 
                   HandleAttributeColumn((XmlSchemaAttribute) obj, table, isBase);
               } 
               else { // XmlSchemaAttributeGroupRef 
                   XmlSchemaAttributeGroupRef attributeGroupRef = (XmlSchemaAttributeGroupRef)obj;
                   XmlSchemaAttributeGroup attributeGroupResolved; 
                   if (attributeGroup.RedefinedAttributeGroup != null && attributeGroupRef.RefName == new XmlQualifiedName(attributeGroup.Name, attributeGroupRef.RefName.Namespace)) {
                       attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroup.RedefinedAttributeGroup;
                   }
                   else { 
                       attributeGroupResolved = (XmlSchemaAttributeGroup)attributeGroups[attributeGroupRef.RefName];
                   } 
                   if (attributeGroupResolved != null) { 
                       HandleAttributeGroup(attributeGroupResolved, table, isBase);
                   } 
               }
           }
       }
        internal void HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren,  bool isNillable){ 
            if (complexTypes.Contains(ct))
                throw ExceptionBuilder.CircularComplexType(ct.Name); 
            bool isBase = false; 
            complexTypes.Add(ct);
 

            if (ct.ContentModel != null) {
                /*
                HandleParticle(ct.CompiledParticle, table, tableChildren, isBase); 
                foreach (XmlSchemaAttribute s in ct.Attributes){
                    HandleAttributeColumn(s, table, isBase); 
                } 
                */
 

                if (ct.ContentModel is XmlSchemaComplexContent) {
                    XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
                    if (cContent is XmlSchemaComplexContentExtension) { 
                        XmlSchemaComplexContentExtension ccExtension = ((XmlSchemaComplexContentExtension) cContent );
                        if (!(ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference)) 
                            HandleAttributes(ccExtension.Attributes, table, isBase); 

                        if (ct.BaseXmlSchemaType is XmlSchemaComplexType) { 
                            HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable);
                        }
                        else {
                            Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType,  "Expected SimpleType or ComplexType"); 
                            if (ccExtension.BaseTypeName.Namespace != Keywords.XSDNS){
                                // this is UDSimpleType, pass Qualified name of type 
                                HandleSimpleContentColumn(ccExtension.BaseTypeName.ToString(), table, isBase, ct.ContentModel.UnhandledAttributes, isNillable); 
                            }
                            else { // it is built in type 
                                HandleSimpleContentColumn(ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
                            }
                        }
                        if (ccExtension.Particle != null) 
                            HandleParticle(ccExtension.Particle, table, tableChildren, isBase);
                        if (ct.BaseXmlSchemaType is XmlSchemaComplexType && this.FromInference) 
                            HandleAttributes(ccExtension.Attributes, table, isBase); 
                    } else {
                        Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction"); 
                        XmlSchemaComplexContentRestriction ccRestriction = ((XmlSchemaComplexContentRestriction) cContent );
                            if (!this.FromInference)
                        HandleAttributes(ccRestriction.Attributes, table, isBase);
                        if (ccRestriction.Particle != null) 
                            HandleParticle(ccRestriction.Particle, table, tableChildren, isBase);
                        if (this.FromInference) 
                            HandleAttributes(ccRestriction.Attributes, table, isBase); 
                    }
                } else { 
                    Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent");
                    XmlSchemaAnnotated cContent = ((XmlSchemaSimpleContent) (ct.ContentModel)).Content;
                    if (cContent is XmlSchemaSimpleContentExtension) {
                        XmlSchemaSimpleContentExtension ccExtension = ((XmlSchemaSimpleContentExtension) cContent ); 
                            HandleAttributes(ccExtension.Attributes, table, isBase);
                        if (ct.BaseXmlSchemaType is XmlSchemaComplexType) { 
                            HandleComplexType((XmlSchemaComplexType)ct.BaseXmlSchemaType, table, tableChildren, isNillable); 
                        }
                        else { 
                            Debug.Assert(ct.BaseXmlSchemaType is XmlSchemaSimpleType,  "Expected SimpleType or ComplexType");
                            HandleSimpleTypeSimpleContentColumn((XmlSchemaSimpleType)ct.BaseXmlSchemaType, ccExtension.BaseTypeName.Name, table, isBase, ct.ContentModel.UnhandledAttributes, isNillable);
                        }
                    } else { 
                        Debug.Assert(cContent is XmlSchemaSimpleContentRestriction, "Expected SimpleContent extension or restriction");
                        XmlSchemaSimpleContentRestriction ccRestriction = ((XmlSchemaSimpleContentRestriction) cContent ); 
                        HandleAttributes(ccRestriction.Attributes, table, isBase); 
                    }
 
                }

            }
            else { 
                isBase = true;
                if (!this.FromInference) 
                    HandleAttributes(ct.Attributes, table, isBase); 
                if (ct.Particle != null)
                    HandleParticle(ct.Particle, table, tableChildren, isBase); 
                if (this.FromInference) {
                    HandleAttributes(ct.Attributes, table, isBase);
                    if (isNillable) // this is for backward compatability to support xsi:Nill=true
                        HandleSimpleContentColumn("string", table, isBase, null, isNillable); 
                }
            } 
 
            complexTypes.Remove(ct);
        } 

        internal XmlSchemaParticle GetParticle(XmlSchemaComplexType ct){
            if (ct.ContentModel != null) {
                if (ct.ContentModel is XmlSchemaComplexContent) { 
                    XmlSchemaAnnotated cContent = ((XmlSchemaComplexContent) (ct.ContentModel)).Content;
                    if (cContent is XmlSchemaComplexContentExtension) { 
                        return ((XmlSchemaComplexContentExtension) cContent ).Particle; 
                    } else {
                        Debug.Assert(cContent is XmlSchemaComplexContentRestriction, "Expected complexContent extension or restriction"); 
                        return ((XmlSchemaComplexContentRestriction) cContent ).Particle;
                    }
                } else {
                    Debug.Assert(ct.ContentModel is XmlSchemaSimpleContent, "expected simpleContent or complexContent"); 
                    return null;
 
                } 

            } 
            else {
                return ct.Particle;
            }
 
        }
 
        internal DataColumn FindField(DataTable table, string field) { 
            bool attribute = false;
            String colName = field; 

            if (field.StartsWith("@", StringComparison.Ordinal)) {
                attribute = true;
                colName = field.Substring(1); 
            }
 
            String [] split = colName.Split(':'); 
            colName = split [split.Length - 1];
 
            colName = XmlConvert.DecodeName(colName);
            DataColumn col = table.Columns[colName];
            if (col == null )
                throw ExceptionBuilder.InvalidField(field); 

            bool _attribute = (col.ColumnMapping == MappingType.Attribute) || (col.ColumnMapping == MappingType.Hidden); 
 
            if  (_attribute != attribute)
                throw ExceptionBuilder.InvalidField(field); 

            return col;
        }
 
        internal DataColumn[] BuildKey(XmlSchemaIdentityConstraint keyNode, DataTable table){
            ArrayList keyColumns = new ArrayList(); 
 
            foreach (XmlSchemaXPath node in keyNode.Fields) {
                keyColumns.Add(FindField(table, node.XPath)); 
            }

            DataColumn [] key = new DataColumn[keyColumns.Count];
            keyColumns.CopyTo(key, 0); 

            return key; 
        } 

        internal bool GetBooleanAttribute(XmlSchemaAnnotated element, String attrName, bool defVal) { 
            string value = GetMsdataAttribute(element, attrName);
            if (value == null || value.Length == 0) {
                return defVal;
            } 
            if ((value == Keywords.TRUE) || (value == Keywords.ONE_DIGIT)){
                return true; 
            } 
            if ((value == Keywords.FALSE) || (value == Keywords.ZERO_DIGIT)){
                return false; 
            }
            // Error processing:
            throw ExceptionBuilder.InvalidAttributeValue(attrName, value);
        } 

        internal String GetStringAttribute(XmlSchemaAnnotated element, String attrName, String defVal) { 
            string value = GetMsdataAttribute(element, attrName); 
            if (value == null || value.Length == 0) {
                return defVal; 
            }
            return value;
        }
 
        /*
         
            ../Customers 
            ID
         
        
            .
            CustID
         
        */
 
        internal static AcceptRejectRule TranslateAcceptRejectRule( string strRule ) { 
            if (strRule == "Cascade")
                return AcceptRejectRule.Cascade; 
            else if (strRule == "None")
                return AcceptRejectRule.None;
            else
                return ForeignKeyConstraint.AcceptRejectRule_Default; 
        }
 
        internal static Rule TranslateRule( string strRule ) { 
            if (strRule == "Cascade")
                return Rule.Cascade; 
            else if (strRule == "None")
                return Rule.None;
            else if (strRule == "SetDefault")
                return Rule.SetDefault; 
            else if (strRule == "SetNull")
                return Rule.SetNull; 
            else 
                return ForeignKeyConstraint.Rule_Default;
        } 

        internal void HandleKeyref(XmlSchemaKeyref keyref) {
            string refer = XmlConvert.DecodeName(keyref.Refer.Name); // check here!!!
            string name = XmlConvert.DecodeName(keyref.Name); 
            name = GetStringAttribute( keyref, "ConstraintName", /*default:*/ name);
 
            // we do not process key defined outside the current node 

            String tableName = GetTableName(keyref); 

            string tableNs = GetMsdataAttribute(keyref,Keywords.MSD_TABLENS);

            DataTable table =  _ds.Tables.GetTableSmart(tableName,tableNs); 

            if (table == null) 
                return; 

            if (refer == null || refer.Length == 0) 
                throw ExceptionBuilder.MissingRefer(name);

            ConstraintTable key = (ConstraintTable) ConstraintNodes[refer];
 
            if (key == null) {
                throw ExceptionBuilder.InvalidKey(name); 
            } 

            DataColumn[] pKey = BuildKey(key.constraint, key.table); 
            DataColumn[] fKey = BuildKey(keyref, table);

            ForeignKeyConstraint fkc = null;
 
            if (GetBooleanAttribute(keyref, Keywords.MSD_CONSTRAINTONLY,  /*default:*/ false)) {
                int iExisting = fKey[0].Table.Constraints.InternalIndexOf(name); 
                if (iExisting > -1) { 
                    if (fKey[0].Table.Constraints[iExisting].ConstraintName != name)
                        iExisting = -1; 
                }

                if (iExisting < 0) {
                    fkc = new ForeignKeyConstraint( name, pKey, fKey ); 
                    fKey[0].Table.Constraints.Add(fkc);
                } 
            } 
            else {
                string relName = XmlConvert.DecodeName(GetStringAttribute( keyref, Keywords.MSD_RELATIONNAME, keyref.Name)); 

                if (relName == null || relName.Length == 0)
                    relName = name;
 
                int iExisting = fKey[0].Table.DataSet.Relations.InternalIndexOf(relName);
                if (iExisting > -1) { 
                    if (fKey[0].Table.DataSet.Relations[iExisting].RelationName != relName) 
                        iExisting = -1;
                } 
                DataRelation relation = null;
                if (iExisting < 0) {
                    relation = new DataRelation(relName, pKey, fKey);
                    SetExtProperties(relation, keyref.UnhandledAttributes); 
                    pKey[0].Table.DataSet.Relations.Add(relation);
 
                    if (FromInference && relation.Nested) { 
                        if (tableDictionary.ContainsKey(relation.ParentTable)) {
                            tableDictionary[relation.ParentTable].Add(relation.ChildTable); 
                        }
                    }

                    fkc = relation.ChildKeyConstraint; 
                    fkc.ConstraintName = name;
                } 
                else { 
                    relation = fKey[0].Table.DataSet.Relations[iExisting];
                } 
                if (GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false)) {
                    relation.Nested = true;
                }
 
            }
 
            string acceptRejectRule = GetMsdataAttribute(keyref, Keywords.MSD_ACCEPTREJECTRULE); 
            string updateRule       = GetMsdataAttribute(keyref, Keywords.MSD_UPDATERULE);
            string deleteRule       = GetMsdataAttribute(keyref, Keywords.MSD_DELETERULE); 

            if (fkc != null) {
                if (acceptRejectRule != null)
                    fkc.AcceptRejectRule = TranslateAcceptRejectRule(acceptRejectRule); 

                if (updateRule != null) 
                    fkc.UpdateRule = TranslateRule(updateRule); 

                if (deleteRule != null) 
                    fkc.DeleteRule = TranslateRule(deleteRule);

                SetExtProperties(fkc, keyref.UnhandledAttributes);
            } 
        }
 
 
        internal void HandleConstraint(XmlSchemaIdentityConstraint keyNode){
            String name = null; 

            name = XmlConvert.DecodeName(keyNode.Name);
            if (name==null || name.Length==0)
                throw ExceptionBuilder.MissingAttribute(Keywords.NAME); 

            if (ConstraintNodes.ContainsKey(name)) 
                throw ExceptionBuilder.DuplicateConstraintRead(name); 

            // we do not process key defined outside the current node 
            String tableName = GetTableName(keyNode);
            string tableNs = GetMsdataAttribute(keyNode,Keywords.MSD_TABLENS);

            DataTable table =  _ds.Tables.GetTableSmart(tableName,tableNs); 

            if (table == null) 
                return; 

            ConstraintNodes.Add(name, new ConstraintTable(table, keyNode)); 

            bool   fPrimaryKey = GetBooleanAttribute(keyNode, Keywords.MSD_PRIMARYKEY,  /*default:*/ false);
            name        = GetStringAttribute(keyNode, "ConstraintName", /*default:*/ name);
 

 
            DataColumn[] key = BuildKey(keyNode, table); 

            if (0 < key.Length) { 
                UniqueConstraint found = (UniqueConstraint) key[0].Table.Constraints.FindConstraint(new UniqueConstraint(name, key));

                if (found == null) {
                    key[0].Table.Constraints.Add(name, key, fPrimaryKey); 
                    SetExtProperties(key[0].Table.Constraints[name], keyNode.UnhandledAttributes);
                } 
                else { 
                        key = found.ColumnsReference;
                        SetExtProperties(found, keyNode.UnhandledAttributes); 
                        if (fPrimaryKey)
                            key[0].Table.PrimaryKey = key;
                    }
                if (keyNode is XmlSchemaKey) { 
                    for (int i=0; i and not null for 
             bool isSimpleContent = ((node.ElementSchemaType.BaseXmlSchemaType != null) ||(ct != null && ct.ContentModel is XmlSchemaSimpleContent));

             if (!FromInference ||(isSimpleContent && table.Columns.Count == 0 )) {// for inference backward compatability 
                 HandleElementColumn(node, table, false);
                 string colName; 
 
                 if (this.FromInference) {
                     int i = 0; 
                     colName = typeName + "_Text";
                     while (table.Columns[colName] != null)
                         colName = colName + i++;
                 } 
                 else {
                     colName = typeName + "_Column"; 
                 } 

                 table.Columns[0].ColumnName = colName; 
                 table.Columns[0].ColumnMapping = MappingType.SimpleContent;
             }

             if (!this.FromInference ||_ds.Tables.GetTable(typeName, _TableUri) == null) { // for inference; special case: add table if doesnot exists in collection 
                _ds.Tables.Add(table);
                if (this.FromInference) { 
                    tableDictionary.Add(table, new List()); 
                }
             } 

            // handle all the unique and key constraints related to this table

            if ((dsElement != null) && (dsElement.Constraints!=null)) { 
                foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) {
                    if (key is XmlSchemaKeyref) 
                        continue; 
                    if (GetTableName(key) == table.TableName)
                        HandleConstraint(key); 
                }
            }
            table.fNestedInDataset = false;
 
            return (table);
        } 
 

        internal string GetInstanceName(XmlSchemaAnnotated node) { 
            string  instanceName = null;

            Debug.Assert( (node is XmlSchemaElement) || (node is XmlSchemaAttribute), "GetInstanceName should only be called on attribute or elements");
 
            if (node is XmlSchemaElement) {
                XmlSchemaElement el = (XmlSchemaElement) node; 
                instanceName = el.Name != null ? el.Name : el.RefName.Name; 
            }
            else if (node is XmlSchemaAttribute) { 
                XmlSchemaAttribute el = (XmlSchemaAttribute) node;
                instanceName = el.Name != null ? el.Name : el.RefName.Name;
            }
 
            Debug.Assert((instanceName != null) && (instanceName.Length != 0), "instanceName cannot be null or empty. There's an error in the XSD compiler");
 
            return instanceName; 
        }
 
        // Sequences of handling Elements, Attributes and Text-only column should be the same as in InferXmlSchema
        internal DataTable InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, bool isRef) {
            DataTable table;
            String typeName = GetInstanceName(node); 
            ArrayList tableChildren = new ArrayList();
 
            String _TableUri; 

            _TableUri = node.QualifiedName.Namespace; 

            table = _ds.Tables.GetTable(XmlConvert.DecodeName(typeName), _TableUri);
// TOD: Do not do this fix
//            if (table == null && node.RefName.IsEmpty && !IsTopLevelElement(node) && _TableUri != null && _TableUri.Length > 0) { 
//                _TableUri = null;    // it means form="qualified", so child element inherits namespace. [....]
//            } 
 
            if (!FromInference || (FromInference && table == null))
            { 
                if (table!=null)
                {
                    if (isRef)
                        return table; 
                    else
                        throw ExceptionBuilder.DuplicateDeclaration(typeName); 
                } 

                if (isRef) 
                    RefTables.Add(_TableUri+":"+typeName);

                table = new DataTable(XmlConvert.DecodeName(typeName) );
                table.TypeName = node.SchemaTypeName; 

                table.Namespace = _TableUri; 
                table.Namespace = GetStringAttribute(node, "targetNamespace", _TableUri); 

                //table.Prefix = node.Prefix; 
                String value= GetStringAttribute(typeNode, Keywords.MSD_CASESENSITIVE,  "") ;
                if (value.Length ==0)
                {
                    value= GetStringAttribute(node, Keywords.MSD_CASESENSITIVE,  "") ; 
                }
                if (0 < value.Length) { 
                    if ((value == Keywords.TRUE) || (value == "True")) 
                        table.CaseSensitive = true;
                    if ((value == Keywords.FALSE) || (value == "False")) 
                        table.CaseSensitive = false;
                }

                value = GetMsdataAttribute(node, Keywords.MSD_LOCALE); 
                if (null != value) { // set by user
                    if (0 < value.Length) { 
                        // <... msdata:Locale="en-US"/> 
                        table.Locale = new CultureInfo(value);
                    } 
                    else {
                        // everett bug behavior before <... msdata:Locale=""/> inherit from DataSet
                        table.Locale = CultureInfo.InvariantCulture;
                    } 
                }
 
                // else inherit from DataSet, not set by user 

                if (!this.FromInference) 
                {
                    table.MinOccurs = node.MinOccurs;
                    table.MaxOccurs = node.MaxOccurs;
                } 
                else
                { 
                    string prefix = GetPrefix(_TableUri); 
                    if (prefix != null)
                        table.Prefix = prefix; 
                }

                _ds.Tables.Add(table);
                if (FromInference) { 
                    tableDictionary.Add(table, new List());
                } 
            } 

            HandleComplexType(typeNode, table, tableChildren, node.IsNillable); 

            for (int i=0; i < table.Columns.Count ; i++)
                table.Columns[i].SetOrdinalInternal(i);
 
/*
            if (xmlContent == XmlContent.Mixed) { 
                string textColumn = GenUniqueColumnName(table.TableName+ "_Text", table); 
                table.XmlText = new DataColumn(textColumn, typeof(string), null, MappingType.Text);
            } */ 

            SetProperties(table, node.UnhandledAttributes);
            SetExtProperties(table, node.UnhandledAttributes);
 
            // handle all the unique and key constraints related to this table
            if ((dsElement != null) && (dsElement.Constraints!=null)) { 
                foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) { 
                    if (key is XmlSchemaKeyref)
                        continue; 
                    if (GetTableName(key) == table.TableName) {
                        // respect the NS if it is specified for key, otherwise just go with table name check
                        if( GetTableNamespace(key) == table.Namespace || GetTableNamespace(key) == null)
                            HandleConstraint(key); 
/*                     if (GetTableNamespace(key) != null) {
                            if (GetTableNamespace(key) == table.Namespace) 
                                HandleConstraint(key); 
                        }
                        else { 
                            HandleConstraint(key);
                        }
*/
                    } 
                }
            } 
 
            foreach(DataTable _tableChild in tableChildren) {
                if (_tableChild != table && table.Namespace == _tableChild.Namespace) 
                    _tableChild.tableNamespace = null;

                if ((dsElement != null) && (dsElement.Constraints!=null)) {
                    foreach (XmlSchemaIdentityConstraint key in dsElement.Constraints) { 
                        XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
                        if (keyref == null) 
                            continue; 

                        bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false); 
                        if (!isNested)
                            continue;
                        if (GetTableName(keyref) == _tableChild.TableName) {
                            if (_tableChild.DataSet.Tables.InternalIndexOf(_tableChild.TableName) < -1) { // if we have multiple tables with the same name 
                                if (GetTableNamespace(keyref) == _tableChild.Namespace) {
                                    HandleKeyref(keyref); 
                                } 
                            }
                            else { 
                                HandleKeyref(keyref);
                            }
                        }
                    } 
                }
 
                DataRelation relation = null; 

                DataRelationCollection childRelations = table.ChildRelations; 
                for (int j = 0; j < childRelations.Count; j++) {
                    if (!childRelations[j].Nested)
                        continue;
 
                    if (_tableChild == childRelations[j].ChildTable)
                        relation = childRelations[j]; 
                } 

                if (relation!=null) 
                    continue;

                DataColumn parentKey;
                if (this.FromInference) { 
                    int position = table.UKColumnPositionForInference;// we keep posiotion of UK column here, for inference
                    if (position == -1) 
                        foreach (DataColumn dc in table.Columns) { 
                        if (dc.ColumnMapping == MappingType.Attribute) {
                            position = dc.Ordinal; 
                            break;
                        }
                    }
                    parentKey = table.AddUniqueKey(position); 

                } 
                else { 
                    parentKey = table.AddUniqueKey();
                } 

                // foreign key in the child table
                DataColumn childKey = _tableChild.AddForeignKey(parentKey);
 
                // when we add  unique key, we do set prefix; but for Fk we do not do . So for backward compatability
                if (this.FromInference) 
                    childKey.Prefix = _tableChild.Prefix; 
//                    childKey.Prefix = GetPrefix(childKey.Namespace);
 
                // create relationship
                // setup relationship between parent and this table
                relation = new DataRelation(table.TableName + "_" + _tableChild.TableName, parentKey, childKey, true);
                relation.Nested = true; 
                _tableChild.DataSet.Relations.Add(relation);
                if (FromInference && relation.Nested) { 
                    if (tableDictionary.ContainsKey(relation.ParentTable)) { 
                        tableDictionary[relation.ParentTable].Add(relation.ChildTable);
                    } 
                }
            }

            return (table); 
        }
 
        private sealed class NameType : IComparable { 
            public readonly String   name;
            public readonly Type     type; 
            public NameType(String n, Type t) {
                name = n;
                type = t;
            } 
            public int CompareTo(object obj) { return String.Compare(name, (string)obj, StringComparison.Ordinal); }
        }; 
 
        public static Type XsdtoClr(string xsdTypeName) {
#if DEBUG 
            for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
                Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
            }
#endif 
            int index = Array.BinarySearch(mapNameTypeXsd, xsdTypeName);
            if (index < 0) { 
                throw ExceptionBuilder.UndefinedDatatype(xsdTypeName); 
            }
            return mapNameTypeXsd[index].type; 
        }

        // XSD spec: http://www.w3.org/TR/xmlschema-2/
        //    April: http://www.w3.org/TR/2000/WD-xmlschema-2-20000407/datatypes.html 
        //    Fabr:  http://www.w3.org/TR/2000/WD-xmlschema-2-20000225/
        private static readonly NameType[] mapNameTypeXsd = { 
            new NameType("ENTITIES"            , typeof(string)  ), /* XSD Apr */ 
            new NameType("ENTITY"              , typeof(string)  ), /* XSD Apr */
            new NameType("ID"                  , typeof(string)  ), /* XSD Apr */ 
            new NameType("IDREF"               , typeof(string)  ), /* XSD Apr */
            new NameType("IDREFS"              , typeof(string)  ), /* XSD Apr */
            new NameType("NCName"              , typeof(string)  ), /* XSD Apr */
            new NameType("NMTOKEN"             , typeof(string)  ), /* XSD Apr */ 
            new NameType("NMTOKENS"            , typeof(string)  ), /* XSD Apr */
            new NameType("NOTATION"            , typeof(string)  ), /* XSD Apr */ 
            new NameType("Name"                , typeof(string)  ), /* XSD Apr */ 
            new NameType("QName"               , typeof(string)  ), /* XSD Apr */
 
            new NameType("anyType"             , typeof(System.Object)  ), /* XSD Apr */
            new NameType("anyURI"              , typeof(System.Uri)  ), /* XSD Apr */
            new NameType("base64Binary"        , typeof(Byte[])  ), /* XSD Apr : abstruct */
            new NameType("boolean"             , typeof(bool)    ), /* XSD Apr */ 
            new NameType("byte"                , typeof(SByte)   ), /* XSD Apr */
            new NameType("date"                , typeof(DateTime)), /* XSD Apr */ 
            new NameType("dateTime"            , typeof(DateTime)), /* XSD Apr */ 
            new NameType("decimal"              , typeof(decimal) ), /* XSD 2001 March */
            new NameType("double"              , typeof(double)  ), /* XSD Apr */ 
            new NameType("duration"            , typeof(TimeSpan)), /* XSD Apr */
            new NameType("float"               , typeof(Single)  ), /* XSD Apr */
            new NameType("gDay"                , typeof(DateTime)), /* XSD Apr */
            new NameType("gMonth"              , typeof(DateTime)), /* XSD Apr */ 
            new NameType("gMonthDay"           , typeof(DateTime)), /* XSD Apr */
            new NameType("gYear"               , typeof(DateTime)), /* XSD Apr */ 
            new NameType("gYearMonth"          , typeof(DateTime)), /* XSD Apr */ 
            new NameType("hexBinary"           , typeof(Byte[])  ), /* XSD Apr : abstruct */
            new NameType("int"                 , typeof(Int32)   ), /* XSD Apr */ 
            new NameType("integer"             , typeof(Int64)   ), /* XSD Apr */
            new NameType("language"            , typeof(string)  ), /* XSD Apr */
            new NameType("long"                , typeof(Int64)   ), /* XSD Apr */
            new NameType("negativeInteger"     , typeof(Int64)   ), /* XSD Apr */ 
            new NameType("nonNegativeInteger"  , typeof(UInt64)  ), /* XSD Apr */
            new NameType("nonPositiveInteger"  , typeof(Int64)   ), /* XSD Apr */ 
            new NameType("normalizedString"    , typeof(string)  ), /* XSD Apr */ 
            new NameType("positiveInteger"     , typeof(UInt64)  ), /* XSD Apr */
            new NameType("short"               , typeof(Int16)   ), /* XSD Apr */ 
            new NameType("string"              , typeof(string)  ), /* XSD Apr */
            new NameType("time"                , typeof(DateTime)), /* XSD Apr */
            new NameType("unsignedByte"        , typeof(Byte)    ), /* XSD Apr */
            new NameType("unsignedInt"         , typeof(UInt32)  ), /* XSD Apr */ 
            new NameType("unsignedLong"        , typeof(UInt64)  ), /* XSD Apr */
            new NameType("unsignedShort"       , typeof(UInt16)  ), /* XSD Apr */ 
        }; 

        private static NameType FindNameType(string name) { 
#if DEBUG
            for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
                Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name);
            } 
#endif
            int index = Array.BinarySearch(mapNameTypeXsd, name); 
            if (index < 0) { 
                throw ExceptionBuilder.UndefinedDatatype(name);
            } 
            return mapNameTypeXsd[index];
        }

        // input param dt is a "qName" for UDSimpleType else it assumes it's a XSD builtin simpleType 
        private Type ParseDataType(string dt) {
            if (!IsXsdType(dt)) { 
                if (udSimpleTypes != null) { 
                    XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) udSimpleTypes[dt];
                    if (simpleType == null) { // it is not named simple type, it is not  XSD type, it should be unsupported type like xs:token 
                        throw ExceptionBuilder.UndefinedDatatype(dt);
                    }
                    SimpleType rootType = new SimpleType(simpleType);
                    while (rootType.BaseSimpleType != null) { 
                        rootType = rootType.BaseSimpleType;
                    } 
 
                    return ParseDataType(rootType.BaseType);
                } 
            }
            NameType nt = FindNameType(dt);
            return nt.type;
        } 
/*  later we may need such a function
        private Boolean IsUDSimpleType(string qname) { 
            if (udSimpleTypes == null) 
                return false;
            return (udSimpleTypes.Contains(qname)); 
        }
*/
        internal static Boolean IsXsdType(string name) {
#if DEBUG 
            for(int i = 1; i < mapNameTypeXsd.Length; ++i) {
                Debug.Assert((mapNameTypeXsd[i-1].CompareTo(mapNameTypeXsd[i].name)) < 0, "incorrect sorting " + mapNameTypeXsd[i].name); 
            } 
#endif
            int index = Array.BinarySearch(mapNameTypeXsd, name); 
            if (index < 0) {
#if DEBUG
                // Let's check that we realy don't have this name:
                foreach (NameType nt in mapNameTypeXsd) { 
                    Debug.Assert(nt.name != name, "FindNameType('" + name + "') -- failed. Existed name not found");
                } 
#endif 
                return false;
            } 
            Debug.Assert(mapNameTypeXsd[index].name == name, "FindNameType('" + name + "') -- failed. Wrong name found");
            return true;
        }
 

        internal XmlSchemaAnnotated FindTypeNode(XmlSchemaAnnotated node) { 
            // this function is returning null 
            // if the typeNode for node is in the XSD namespace.
 
            XmlSchemaAttribute attr = node as XmlSchemaAttribute;
            XmlSchemaElement el = node as XmlSchemaElement;
            bool isAttr = false;
            if (attr != null) { 
                isAttr = true;
            } 
 
            String _type = isAttr ? attr.SchemaTypeName.Name :  el.SchemaTypeName.Name;
            String _typeNs = isAttr ? attr.SchemaTypeName.Namespace :  el.SchemaTypeName.Namespace; 
            if (_typeNs == Keywords.XSDNS)
                return null;
            XmlSchemaAnnotated typeNode;
            if (_type == null || _type.Length == 0) { 
                _type = isAttr ? attr.RefName.Name :  el.RefName.Name;
                if (_type == null || _type.Length == 0) 
                    typeNode = (XmlSchemaAnnotated) (isAttr ? attr.SchemaType :  el.SchemaType); 
                else
                    typeNode = isAttr ? FindTypeNode((XmlSchemaAnnotated)attributes[attr.RefName]) :FindTypeNode((XmlSchemaAnnotated)elementsTable[el.RefName]); 
            }
            else
                typeNode = (XmlSchemaAnnotated)schemaTypes[isAttr ? ((XmlSchemaAttribute)node).SchemaTypeName :  ((XmlSchemaElement)node).SchemaTypeName];
            return typeNode; 
        }
 
 
    internal void HandleSimpleTypeSimpleContentColumn(XmlSchemaSimpleType typeNode, string strType, DataTable table, bool isBase, XmlAttribute[] attrs, bool isNillable){
            // disallow multiple simple content columns for the table 
            if(FromInference && table.XmlText != null) { // backward compatability for inference
                return;
            }
 
            Type type = null;
            SimpleType xsdType = null; 
 
//            if (typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType
            if (typeNode.QualifiedName.Name != null && typeNode.QualifiedName.Name.Length != 0 && typeNode.QualifiedName.Namespace != Keywords.XSDNS) { // this means UDSimpleType 
                xsdType = new SimpleType(typeNode);
                strType = typeNode.QualifiedName.ToString(); // use qualifed name
                type = ParseDataType(typeNode.QualifiedName.ToString());
            } 
            else {// previous code V 1.1
                XmlSchemaSimpleType ancestor = typeNode.BaseXmlSchemaType as XmlSchemaSimpleType; 
                if ((ancestor != null) && (ancestor.QualifiedName.Namespace != Keywords.XSDNS)) { 
                    xsdType = new SimpleType(typeNode);
                    SimpleType rootType = xsdType; 

                    while (rootType.BaseSimpleType != null) {
                        rootType = rootType.BaseSimpleType;
                    } 
                    type = ParseDataType(rootType.BaseType);
                    strType = xsdType.Name; 
                } 
                else {
                    type = ParseDataType(strType); 
                }
            }

 
            DataColumn column;
 
            string colName; 
            if (this.FromInference) {
                int i = 0; 
                colName = table.TableName + "_Text";
                while (table.Columns[colName] != null) {
                    colName = colName + i++;
                } 
            }
            else 
                colName = table.TableName + "_text"; 

            string columnName = colName; 
            bool isToAdd = true;
            if ((!isBase) && (table.Columns.Contains(columnName, true))){
                column = table.Columns[columnName];
                isToAdd = false; 
            }
            else { 
                column = new DataColumn(columnName, type, null, MappingType.SimpleContent); 
            }
 
            SetProperties(column, attrs);
            HandleColumnExpression(column, attrs);
            SetExtProperties(column, attrs);
 
            String tmp = "-1";
            string defValue = null; 
            //try to see if attributes contain allownull 
            column.AllowDBNull = isNillable;
 
            if(attrs!=null)
                for(int i=0; i< attrs.Length;i++) {
                    if ( attrs[i].LocalName == Keywords.MSD_ALLOWDBNULL &&  attrs[i].NamespaceURI == Keywords.MSDNS)
                        if ( attrs[i].Value == Keywords.FALSE) 
                            column.AllowDBNull = false;
                    if ( attrs[i].LocalName == Keywords.MSD_ORDINAL &&  attrs[i].NamespaceURI == Keywords.MSDNS) 
                        tmp = attrs[i].Value; 
                    if ( attrs[i].LocalName == Keywords.MSD_DEFAULTVALUE &&  attrs[i].NamespaceURI == Keywords.MSDNS)
                        defValue = attrs[i].Value; 
                }
            int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);

 
            //SetExtProperties(column, attr.UnhandledAttributes);
 
            if ((column.Expression!=null)&&(column.Expression.Length!=0)) { 
                ColumnExpressions.Add(column);
            } 

// Patch 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.Namespace = typeNode.SourceUri; 
            if (isToAdd) {
                if (this.FromInference) { 
                    column.Prefix = GetPrefix(table.Namespace); 
                    column.AllowDBNull = true;
                } 
                if(ordinal>-1 && ordinal-1 && ordinal 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 (this.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);
                }
        } 

        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);
            }
 
// Patch 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"); 
            int ordinal = (int)Convert.ChangeType(tmp, typeof(int), null);
 
            if(isToAdd) {
                if(ordinal>-1 && ordinal tableSequenceList = new List(); 

            String value = GetMsdataAttribute(node, Keywords.MSD_LOCALE); 
            if (null != value) { // set by user 
                if (0 != value.Length) {
                    // <... msdata:Locale="en-US"/> 
                    _ds.Locale = new CultureInfo(value);
                }
                else {
                    // everett bug behavior before <... msdata:Locale=""/> becoming CultureInfo(0x409) 
                    _ds.Locale = CultureInfo.InvariantCulture;
                } 
            } 
            else { // not set by user
                // MSD_LOCALE overrides MSD_USECURRENTLOCALE 
                if (GetBooleanAttribute(node, Keywords.MSD_USECURRENTLOCALE, false)) {
                    _ds.SetLocaleValue(CultureInfo.CurrentCulture, false);
                }
                else { 
                    // everett behavior before <... msdata:UseCurrentLocale="true"/>
                    _ds.SetLocaleValue(new CultureInfo(0x409), false); 
                } 
            }
 
            // reuse variable
            value =  GetMsdataAttribute(node, Keywords.MSD_DATASETNAME);
            if (value!=null && value.Length != 0) {
                dsName = value; 
            }
 
            value =  GetMsdataAttribute(node, Keywords.MSD_DATASETNAMESPACE); 
            if (value!=null && value.Length != 0) {
                dsNamespace = value; 
            }

            SetProperties(_ds, node.UnhandledAttributes);
            SetExtProperties(_ds, node.UnhandledAttributes); 

 
            if (dsName != null && dsName.Length != 0) 
                _ds.DataSetName = XmlConvert.DecodeName(dsName);
 
 //            _ds.Namespace = node.QualifiedName.Namespace;
            _ds.Namespace = dsNamespace;

            if (this.FromInference) 
                _ds.Prefix = GetPrefix(_ds.Namespace);
 
            XmlSchemaComplexType ct = (XmlSchemaComplexType) FindTypeNode(node); 
            if (ct.Particle != null) {
                XmlSchemaObjectCollection items = GetParticleItems(ct.Particle); 

                if (items == null) {
                    return;
                } 

                foreach (XmlSchemaAnnotated el in items){ 
                    if (el is XmlSchemaElement) { 
                        if(((XmlSchemaElement)el).RefName.Name.Length != 0) {
                            if (!FromInference) { 
                                continue;
                            }
                            else {
                                DataTable tempTable = _ds.Tables.GetTable(XmlConvert.DecodeName(GetInstanceName((XmlSchemaElement)el)), node.QualifiedName.Namespace); 
                                if (tempTable != null) {
                                    tableSequenceList.Add(tempTable); // if ref table is created, add it 
                                } 
                                bool isComplexTypeOrValidElementType = false;
                                if (node.ElementSchemaType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType)) { 
                                    isComplexTypeOrValidElementType = true;
                                }
 //                          bool isComplexTypeOrValidElementType = (node.ElementType != null || !(((XmlSchemaElement)el).SchemaType is XmlSchemaComplexType));
                                if ((((XmlSchemaElement)el).MaxOccurs != Decimal.One )  && (!isComplexTypeOrValidElementType)) { 
                                    continue;
                                } 
                            } 
                        }
 
                        DataTable child = HandleTable ((XmlSchemaElement)el);
                        if (child!=null) {
                            child.fNestedInDataset = true;
                        } 
                        if (FromInference) {
                            tableSequenceList.Add(child); 
                        } 
                    }
                    else if (el is XmlSchemaChoice){ // should we check for inference? 
                        XmlSchemaObjectCollection choiceItems = ((XmlSchemaChoice)el).Items;
                        if (choiceItems == null)
                            continue;
                        foreach (XmlSchemaAnnotated choiceEl in choiceItems) { 
                            if (choiceEl is XmlSchemaElement) {
                                if (((XmlSchemaParticle)el).MaxOccurs > Decimal.One && (((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)) // amir 
                                ((XmlSchemaElement)choiceEl).MaxOccurs = ((XmlSchemaParticle)el).MaxOccurs; 
                                if ((((XmlSchemaElement)choiceEl).RefName.Name.Length != 0) && (!FromInference && ((XmlSchemaElement)choiceEl).MaxOccurs != Decimal.One && !(((XmlSchemaElement)choiceEl).SchemaType is XmlSchemaComplexType)))
                                    continue; 

                                DataTable child = HandleTable ((XmlSchemaElement)choiceEl);
                                if (FromInference) {
                                    tableSequenceList.Add(child); 
                                }
                                if (child != null) 
                                { 
                                    child.fNestedInDataset = true;
                                } 
                            }
                        }
                    }
                } 
            }
 
            // Handle the non-nested keyref constraints 
            if (node.Constraints != null) {
                foreach (XmlSchemaIdentityConstraint key in node.Constraints) { 
                        XmlSchemaKeyref keyref = key as XmlSchemaKeyref;
                        if (keyref == null)
                            continue;
 
                        bool isNested = GetBooleanAttribute(keyref, Keywords.MSD_ISNESTED,  /*default:*/ false);
                        if (isNested) 
                            continue; 

                        HandleKeyref(keyref); 
                    }
            }
            if (FromInference && isNewDataSet) {
                List _tableList = new List(_ds.Tables.Count); 
                foreach(DataTable dt in tableSequenceList) {
                    AddTablesToList(_tableList, dt); 
                } 
                _ds.Tables.ReplaceFromInference(_tableList); // replace the list with the one in correct order: BackWard compatability for inference
            } 
        }

        private void AddTablesToList(List tableList, DataTable dt) { // kind of depth _first travarsal
            if (!tableList.Contains(dt)) { 
                tableList.Add(dt);
                foreach(DataTable childTable in tableDictionary[dt]) { 
                    AddTablesToList(tableList, childTable); 
                }
            } 
        }

        private string GetPrefix(string ns) {
            if (ns == null) 
                return null;
            foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) { 
                XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray(); 
                for(int i = 0; i < qualifiedNames.Length; i++) {
                    if (qualifiedNames[i].Namespace == ns) 
                        return qualifiedNames[i].Name;
                }
            }
            return null; 
        }
 
        private string GetNamespaceFromPrefix(string prefix) { 
            if ((prefix == null) ||(prefix.Length == 0))
                return null; 
            foreach (XmlSchema schemaRoot in _schemaSet.Schemas()) {
                XmlQualifiedName[] qualifiedNames = schemaRoot.Namespaces.ToArray();
                for(int i = 0; i < qualifiedNames.Length; i++) {
                    if (qualifiedNames[i].Name == prefix) 
                        return qualifiedNames[i].Namespace;
                } 
            } 
            return null;
        } 


        private String GetTableNamespace(XmlSchemaIdentityConstraint key) {
            string xpath = key.Selector.XPath; 
            string [] split = xpath.Split('/');
            string prefix =string.Empty; 
 
            string QualifiedTableName = split[split.Length - 1]; //get the last string after '/' and ':'
 
            if ((QualifiedTableName == null) || (QualifiedTableName.Length == 0))
                throw ExceptionBuilder.InvalidSelector(xpath);

            if (QualifiedTableName.IndexOf(':') != -1) 
                prefix = QualifiedTableName.Substring(0, QualifiedTableName.IndexOf(':'));
            else 
                return GetMsdataAttribute(key, Keywords.MSD_TABLENS); 

            prefix  = XmlConvert.DecodeName(prefix ); 

            return GetNamespaceFromPrefix(prefix);
        }
 
        private String GetTableName(XmlSchemaIdentityConstraint key) {
            string xpath = key.Selector.XPath; 
            string [] split = xpath.Split('/',':'); 
            String tableName = split[split.Length - 1]; //get the last string after '/' and ':'
 
            if ((tableName == null) || (tableName.Length == 0))
                throw ExceptionBuilder.InvalidSelector(xpath);

            tableName = XmlConvert.DecodeName(tableName); 
            return tableName;
        } 
 
        internal bool IsTable(XmlSchemaElement node) {
            if (node.MaxOccurs == decimal.Zero) 
                return false;

            XmlAttribute[] attribs = node.UnhandledAttributes;
            if (attribs != null) { 
                for(int i = 0; i < attribs.Length; i++) {
                    XmlAttribute attrib = attribs[i]; 
                    if (attrib.LocalName == Keywords.MSD_DATATYPE && 
                        attrib.Prefix == Keywords.MSD &&
                        attrib.NamespaceURI == Keywords.MSDNS) 
                        return false;
                }
            }
 
            Object typeNode = FindTypeNode(node);
 
            if ( (node.MaxOccurs > decimal.One) && typeNode == null ){ 
                return true;
            } 


            if ((typeNode==null) || !(typeNode is XmlSchemaComplexType)) {
                return false; 
            }
 
            XmlSchemaComplexType ctNode = (XmlSchemaComplexType) typeNode; 

            if (ctNode.IsAbstract) 
                throw ExceptionBuilder.CannotInstantiateAbstract(node.Name);

            return true;
        } 

//        internal bool IsTopLevelElement (XmlSchemaElement node) { 
//            return (elements.IndexOf(node) != -1); 
//        }
        internal DataTable HandleTable(XmlSchemaElement node) { 

            if (!IsTable(node))
                return null;
 
            Object typeNode = FindTypeNode(node);
 
            if ( (node.MaxOccurs > decimal.One) && typeNode == null ){ 
                return InstantiateSimpleTable(node);
            } 

            DataTable table = InstantiateTable(node,(XmlSchemaComplexType)typeNode, (node.RefName != null)); // this is wrong , correct check should be node.RefName.IsEmpty

            table.fNestedInDataset = false; 
            return table;
 
        } 

    } 

    internal sealed class XmlIgnoreNamespaceReader : XmlNodeReader {
        private List namespacesToIgnore;
    // 
    // Constructor
    // 
        internal XmlIgnoreNamespaceReader(XmlDocument xdoc, string[] namespacesToIgnore) : base(xdoc) { 
            this.namespacesToIgnore = new List(namespacesToIgnore);
        } 

    //
    // XmlReader implementation
    // 

        public override bool MoveToFirstAttribute() { 
            if (base.MoveToFirstAttribute()) { 
                if ( namespacesToIgnore.Contains(this.NamespaceURI) ||
                    (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) { //try next one 
                    return MoveToNextAttribute();
                }
                else {
                    return true; 
                }
            } 
            return false; 
        }
 
        public override bool MoveToNextAttribute() {
            bool moved, flag;
            do {
                moved = false; 
                flag = false;
                if (base.MoveToNextAttribute()) { 
                    moved = true; 

                    if ( namespacesToIgnore.Contains(this.NamespaceURI) || 
                        (this.NamespaceURI == Keywords.XML_XMLNS && this.LocalName != "lang")) {
                        flag = true;
                    }
                } 
            } while(flag);
            return moved; 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK