SchemaExporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / WCF / Serialization / System / Runtime / Serialization / SchemaExporter.cs / 1305376 / SchemaExporter.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------

namespace System.Runtime.Serialization 
{
    using System; 
    using System.Collections; 
    using System.Collections.Generic;
    using System.Collections.ObjectModel; 
    using System.Diagnostics;
    using System.Globalization;
    using System.IO;
    using System.Reflection; 
    using System.Runtime.Diagnostics;
    using System.ServiceModel.Diagnostics; 
    using System.Security; 
    using System.Xml;
    using System.Xml.Schema; 
    using System.Xml.Serialization;
    using System.Runtime.Serialization.Diagnostics;

    class SchemaExporter 
    {
        XmlSchemaSet schemas; 
        XmlDocument xmlDoc; 
        DataContractSet dataContractSet;
 
        internal SchemaExporter(XmlSchemaSet schemas, DataContractSet dataContractSet)
        {
            this.schemas = schemas;
            this.dataContractSet = dataContractSet; 
        }
 
        XmlSchemaSet Schemas 
        {
            get { return schemas; } 
        }

        XmlDocument XmlDoc
        { 
            get
            { 
                if (xmlDoc == null) 
                    xmlDoc = new XmlDocument();
                return xmlDoc; 
            }
        }

        internal void Export() 
        {
            try 
            { 
                // Remove this if we decide to publish serialization schema at well-known location
                ExportSerializationSchema(); 
                foreach (KeyValuePair pair in dataContractSet)
                {
                    DataContract dataContract = pair.Value;
                    if (!dataContractSet.IsContractProcessed(dataContract)) 
                    {
                        ExportDataContract(dataContract); 
                        dataContractSet.SetContractProcessed(dataContract); 
                    }
                } 
            }
            finally
            {
                xmlDoc = null; 
                dataContractSet = null;
            } 
        } 

        void ExportSerializationSchema() 
        {
            if (!Schemas.Contains(Globals.SerializationNamespace))
            {
                StringReader reader = new StringReader(Globals.SerializationSchema); 
                XmlSchema schema = XmlSchema.Read(reader, null);
                if (schema == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace))); 
                Schemas.Add(schema);
            } 
        }

        void ExportDataContract(DataContract dataContract)
        { 
            if (dataContract.IsBuiltInDataContract)
                return; 
            else if (dataContract is XmlDataContract) 
                ExportXmlDataContract((XmlDataContract)dataContract);
            else 
            {
                XmlSchema schema = GetSchema(dataContract.StableName.Namespace);

                if (dataContract is ClassDataContract) 
                {
                    ClassDataContract classDataContract = (ClassDataContract)dataContract; 
                    if (classDataContract.IsISerializable) 
                        ExportISerializableDataContract(classDataContract, schema);
                    else 
                        ExportClassDataContract(classDataContract, schema);
                }
                else if (dataContract is CollectionDataContract)
                    ExportCollectionDataContract((CollectionDataContract)dataContract, schema); 
                else if (dataContract is EnumDataContract)
                    ExportEnumDataContract((EnumDataContract)dataContract, schema); 
                ExportTopLevelElement(dataContract, schema); 
                Schemas.Reprocess(schema);
            } 
        }

        XmlSchemaElement ExportTopLevelElement(DataContract dataContract, XmlSchema schema)
        { 
            if (schema == null || dataContract.StableName.Namespace != dataContract.TopLevelElementNamespace.Value)
                schema = GetSchema(dataContract.TopLevelElementNamespace.Value); 
 
            XmlSchemaElement topLevelElement = new XmlSchemaElement();
            topLevelElement.Name = dataContract.TopLevelElementName.Value; 
            SetElementType(topLevelElement, dataContract, schema);
            topLevelElement.IsNillable = true;
            schema.Items.Add(topLevelElement);
            return topLevelElement; 
        }
 
        void ExportClassDataContract(ClassDataContract classDataContract, XmlSchema schema) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType(); 
            type.Name = classDataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null;
            if (classDataContract.UnderlyingType.IsGenericType) 
                genericInfoElement = ExportGenericInfo(classDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace);
 
            XmlSchemaSequence rootSequence = new XmlSchemaSequence(); 
            for (int i=0; i < classDataContract.Members.Count; i++)
            { 
                DataMember dataMember = classDataContract.Members[i];

                XmlSchemaElement element = new XmlSchemaElement();
                element.Name = dataMember.Name; 
                XmlElement actualTypeElement=null;
                DataContract memberTypeContract = dataContractSet.GetMemberTypeDataContract(dataMember); 
                if (CheckIfMemberHasConflict(dataMember)) 
                {
                    element.SchemaTypeName = AnytypeQualifiedName; 
                    actualTypeElement = ExportActualType(memberTypeContract.StableName);
                    SchemaHelper.AddSchemaImport(memberTypeContract.StableName.Namespace, schema);
                }
                else 
                    SetElementType(element, memberTypeContract, schema);
                SchemaHelper.AddElementForm(element, schema); 
                if (dataMember.IsNullable) 
                    element.IsNillable = true;
                if (!dataMember.IsRequired) 
                    element.MinOccurs = 0;

                element.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(dataMember), ExportEmitDefaultValue(dataMember));
                rootSequence.Items.Add(element); 
            }
 
            XmlElement isValueTypeElement = null; 
            if (classDataContract.BaseContract != null)
            { 
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, classDataContract.BaseContract.StableName, schema);
                extension.Particle = rootSequence;
                if (classDataContract.IsReference && !classDataContract.BaseContract.IsReference)
                { 
                    AddReferenceAttributes(extension.Attributes, schema);
                } 
            } 
            else
            { 
                type.Particle = rootSequence;
                if (classDataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(classDataContract.IsValueType), schema);
                if (classDataContract.IsReference) 
                    AddReferenceAttributes(type.Attributes, schema);
            } 
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(classDataContract), isValueTypeElement); 
        }
 
        void AddReferenceAttributes(XmlSchemaObjectCollection attributes, XmlSchema schema)
        {
            SchemaHelper.AddSchemaImport(Globals.SerializationNamespace, schema);
            schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace); 
            attributes.Add(IdAttribute);
            attributes.Add(RefAttribute); 
        } 

        void SetElementType(XmlSchemaElement element, DataContract dataContract, XmlSchema schema) 
        {
            XmlDataContract xmlDataContract = dataContract as XmlDataContract;
            if (xmlDataContract != null && xmlDataContract.IsAnonymous)
            { 
                element.SchemaType = xmlDataContract.XsdType;
            } 
            else 
            {
                element.SchemaTypeName = dataContract.StableName; 

                if (element.SchemaTypeName.Namespace.Equals(Globals.SerializationNamespace))
                    schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace);
 
                SchemaHelper.AddSchemaImport(dataContract.StableName.Namespace, schema);
            } 
        } 

        bool CheckIfMemberHasConflict(DataMember dataMember) 
        {
            if (dataMember.HasConflictingNameAndType)
                return true;
 
            DataMember conflictingMember = dataMember.ConflictingMember;
            while (conflictingMember != null) 
            { 
                if (conflictingMember.HasConflictingNameAndType)
                    return true; 
                conflictingMember = conflictingMember.ConflictingMember;
            }

            return false; 
        }
 
        private XmlElement ExportEmitDefaultValue(DataMember dataMember) 
        {
            if (dataMember.EmitDefaultValue) 
                return null;
            XmlElement defaultValueElement = XmlDoc.CreateElement(DefaultValueAnnotation.Name, DefaultValueAnnotation.Namespace);
            XmlAttribute emitDefaultValueAttribute = XmlDoc.CreateAttribute(Globals.EmitDefaultValueAttribute);
            emitDefaultValueAttribute.Value = Globals.False; 
            defaultValueElement.Attributes.Append(emitDefaultValueAttribute);
            return defaultValueElement; 
 
        }
 
        XmlElement ExportActualType(XmlQualifiedName typeName)
        {
            return ExportActualType(typeName, XmlDoc);
        } 

        static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc) 
        { 
            XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
 
            XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
            nameAttribute.Value = typeName.Name;
            actualTypeElement.Attributes.Append(nameAttribute);
 
            XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
            nsAttribute.Value = typeName.Namespace; 
            actualTypeElement.Attributes.Append(nsAttribute); 

            return actualTypeElement; 
        }

        XmlElement ExportGenericInfo(Type clrType, string elementName, string elementNs)
        { 
            Type itemType;
            int nestedCollectionLevel = 0; 
            while (CollectionDataContract.IsCollection(clrType, out itemType)) 
            {
                if (DataContract.GetBuiltInDataContract(clrType) != null 
                    || CollectionDataContract.IsCollectionDataContract(clrType))
                {
                    break;
                } 
                clrType = itemType;
                nestedCollectionLevel++; 
            } 

            Type[] genericArguments = null; 
            IList genericArgumentCounts = null;
            if (clrType.IsGenericType)
            {
                genericArguments = clrType.GetGenericArguments(); 
                string typeName;
                if (clrType.DeclaringType == null) 
                    typeName = clrType.Name; 
                else
                { 
                    int nsLen = (clrType.Namespace == null) ? 0 : clrType.Namespace.Length;
                    if (nsLen > 0)
                        nsLen++; //include the . following namespace
                    typeName = DataContract.GetClrTypeFullName(clrType).Substring(nsLen).Replace('+', '.'); 
                }
                int iParam = typeName.IndexOf('['); 
                if (iParam >= 0) 
                    typeName = typeName.Substring(0, iParam);
                genericArgumentCounts = DataContract.GetDataContractNameForGenericName(typeName, null); 
                clrType = clrType.GetGenericTypeDefinition();
            }
            XmlQualifiedName dcqname = DataContract.GetStableName(clrType);
            if (nestedCollectionLevel > 0) 
            {
                string collectionName = dcqname.Name; 
                for (int n = 0; n < nestedCollectionLevel; n++) 
                    collectionName = Globals.ArrayPrefix + collectionName;
                dcqname = new XmlQualifiedName(collectionName, DataContract.GetCollectionNamespace(dcqname.Namespace)); 
            }
            XmlElement typeElement = XmlDoc.CreateElement(elementName, elementNs);

            XmlAttribute nameAttribute = XmlDoc.CreateAttribute(Globals.GenericNameAttribute); 
            nameAttribute.Value = genericArguments != null ? XmlConvert.DecodeName(dcqname.Name) : dcqname.Name;
            //nameAttribute.Value = dcqname.Name; 
            typeElement.Attributes.Append(nameAttribute); 

            XmlAttribute nsAttribute = XmlDoc.CreateAttribute(Globals.GenericNamespaceAttribute); 
            nsAttribute.Value = dcqname.Namespace;
            typeElement.Attributes.Append(nsAttribute);

            if (genericArguments != null) 
            {
                int argIndex = 0; 
                int nestedLevel = 0; 
                foreach (int genericArgumentCount in genericArgumentCounts)
                { 
                    for (int i = 0; i < genericArgumentCount; i++, argIndex++)
                    {
                        XmlElement argumentElement = ExportGenericInfo(genericArguments[argIndex], Globals.GenericParameterLocalName, Globals.SerializationNamespace);
                        if (nestedLevel > 0) 
                        {
                            XmlAttribute nestedLevelAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute); 
                            nestedLevelAttribute.Value = nestedLevel.ToString(CultureInfo.InvariantCulture); 
                            argumentElement.Attributes.Append(nestedLevelAttribute);
                        } 
                        typeElement.AppendChild(argumentElement);
                    }
                    nestedLevel++;
                } 
                if (genericArgumentCounts[nestedLevel - 1] == 0)
                { 
                    XmlAttribute typeNestedLevelsAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute); 
                    typeNestedLevelsAttribute.Value = genericArgumentCounts.Count.ToString(CultureInfo.InvariantCulture);
                    typeElement.Attributes.Append(typeNestedLevelsAttribute); 
                }
            }

            return typeElement; 
        }
 
        XmlElement ExportSurrogateData(object key) 
        {
            object surrogateData = dataContractSet.GetSurrogateData(key); 
            if (surrogateData == null)
                return null;
            StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
            XmlWriterSettings writerSettings = new XmlWriterSettings(); 
            writerSettings.OmitXmlDeclaration = true;
            XmlWriter xmlWriter = XmlWriter.Create(stringWriter, writerSettings); 
            Collection knownTypes = new Collection(); 
            DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes);
            DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject, 
                SurrogateDataAnnotationName.Name, SurrogateDataAnnotationName.Namespace, knownTypes, Int32.MaxValue,
                false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
            serializer.WriteObject(xmlWriter, surrogateData);
            xmlWriter.Flush(); 
            return (XmlElement)XmlDoc.ReadNode(XmlReader.Create(new StringReader(stringWriter.ToString())));
        } 
 
        void ExportCollectionDataContract(CollectionDataContract collectionDataContract, XmlSchema schema)
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = collectionDataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null, isDictionaryElement = null; 
            if (collectionDataContract.UnderlyingType.IsGenericType && CollectionDataContract.IsCollectionDataContract(collectionDataContract.UnderlyingType))
                genericInfoElement = ExportGenericInfo(collectionDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace); 
            if (collectionDataContract.IsDictionary) 
                isDictionaryElement = ExportIsDictionary();
            type.Annotation = GetSchemaAnnotation(isDictionaryElement, genericInfoElement, ExportSurrogateData(collectionDataContract)); 

            XmlSchemaSequence rootSequence = new XmlSchemaSequence();

            XmlSchemaElement element = new XmlSchemaElement(); 
            element.Name = collectionDataContract.ItemName;
            element.MinOccurs = 0; 
            element.MaxOccursString = Globals.OccursUnbounded; 
            if (collectionDataContract.IsDictionary)
            { 
                ClassDataContract keyValueContract = collectionDataContract.ItemContract as ClassDataContract;
                XmlSchemaComplexType keyValueType = new XmlSchemaComplexType();
                XmlSchemaSequence keyValueSequence = new XmlSchemaSequence();
                foreach (DataMember dataMember in keyValueContract.Members) 
                {
                    XmlSchemaElement keyValueElement = new XmlSchemaElement(); 
                    keyValueElement.Name = dataMember.Name; 
                    SetElementType(keyValueElement, dataContractSet.GetMemberTypeDataContract(dataMember), schema);
                    SchemaHelper.AddElementForm(keyValueElement, schema); 
                    if (dataMember.IsNullable)
                        keyValueElement.IsNillable = true;
                    keyValueElement.Annotation = GetSchemaAnnotation(ExportSurrogateData(dataMember));
                    keyValueSequence.Items.Add(keyValueElement); 
                }
                keyValueType.Particle = keyValueSequence; 
                element.SchemaType = keyValueType; 
            }
            else 
            {
                if (collectionDataContract.IsItemTypeNullable)
                    element.IsNillable = true;
                DataContract itemContract = dataContractSet.GetItemTypeDataContract(collectionDataContract); 
                SetElementType(element, itemContract, schema);
            } 
            SchemaHelper.AddElementForm(element, schema); 
            rootSequence.Items.Add(element);
 
            type.Particle = rootSequence;

            if (collectionDataContract.IsReference)
                AddReferenceAttributes(type.Attributes, schema); 
        }
 
        XmlElement ExportIsDictionary() 
        {
            XmlElement isDictionaryElement = XmlDoc.CreateElement(IsDictionaryAnnotationName.Name, IsDictionaryAnnotationName.Namespace); 
            isDictionaryElement.InnerText = Globals.True;
            return isDictionaryElement;
        }
 
        void ExportEnumDataContract(EnumDataContract enumDataContract, XmlSchema schema)
        { 
            XmlSchemaSimpleType type = new XmlSchemaSimpleType(); 
            type.Name = enumDataContract.StableName.Name;
            XmlElement actualTypeElement = (enumDataContract.BaseContractName == DefaultEnumBaseTypeName) ? null : ExportActualType(enumDataContract.BaseContractName); 
            type.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(enumDataContract));
            schema.Items.Add(type);

            XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction(); 
            restriction.BaseTypeName = StringQualifiedName;
            SchemaHelper.AddSchemaImport(enumDataContract.BaseContractName.Namespace, schema); 
            if (enumDataContract.Values != null) 
            {
                for (int i = 0; i < enumDataContract.Values.Count; i++) 
                {
                    XmlSchemaEnumerationFacet facet = new XmlSchemaEnumerationFacet();
                    facet.Value = enumDataContract.Members[i].Name;
                    if (enumDataContract.Values[i] != GetDefaultEnumValue(enumDataContract.IsFlags, i)) 
                        facet.Annotation = GetSchemaAnnotation(EnumerationValueAnnotationName, enumDataContract.GetStringFromEnumValue(enumDataContract.Values[i]), schema);
                    restriction.Facets.Add(facet); 
                } 
            }
            if (enumDataContract.IsFlags) 
            {
                XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                XmlSchemaSimpleType anonymousType = new XmlSchemaSimpleType();
                anonymousType.Content = restriction; 
                list.ItemType = anonymousType;
                type.Content = list; 
            } 
            else
                type.Content = restriction; 
        }

        internal static long GetDefaultEnumValue(bool isFlags, int index)
        { 
            return isFlags ? (long)Math.Pow(2, index) : index;
        } 
 
        void ExportISerializableDataContract(ClassDataContract dataContract, XmlSchema schema)
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = dataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null; 
            if (dataContract.UnderlyingType.IsGenericType)
                genericInfoElement = ExportGenericInfo(dataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace); 
 
            XmlElement isValueTypeElement = null;
            if (dataContract.BaseContract != null) 
            {
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, dataContract.BaseContract.StableName, schema);
            }
            else 
            {
                schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace); 
                type.Particle = ISerializableSequence; 
                XmlSchemaAttribute iSerializableFactoryTypeAttribute = ISerializableFactoryTypeAttribute;
                type.Attributes.Add(iSerializableFactoryTypeAttribute); 
                SchemaHelper.AddSchemaImport(ISerializableFactoryTypeAttribute.RefName.Namespace, schema);
                if (dataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema);
            } 
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(dataContract), isValueTypeElement);
        } 
 
        XmlSchemaComplexContentExtension CreateTypeContent(XmlSchemaComplexType type, XmlQualifiedName baseTypeName, XmlSchema schema)
        { 
            SchemaHelper.AddSchemaImport(baseTypeName.Namespace, schema);

            XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
            extension.BaseTypeName = baseTypeName; 
            type.ContentModel = new XmlSchemaComplexContent();
            type.ContentModel.Content = extension; 
 
            return extension;
        } 

        void ExportXmlDataContract(XmlDataContract dataContract)
        {
            XmlQualifiedName typeQName; 
            bool hasRoot;
            XmlSchemaType xsdType; 
 
            Type clrType = dataContract.UnderlyingType;
            if (!IsSpecialXmlType(clrType, out typeQName, out xsdType, out hasRoot)) 
                if (!InvokeSchemaProviderMethod(clrType, schemas, out typeQName, out xsdType, out hasRoot))
                    InvokeGetSchemaMethod(clrType, schemas, typeQName);

            if (hasRoot) 
            {
                if (!(typeQName.Equals(dataContract.StableName))) 
                { 
                    Fx.Assert("XML data contract type name does not match schema name");
                } 

                XmlSchema schema;
                if (SchemaHelper.GetSchemaElement(Schemas,
                    new XmlQualifiedName(dataContract.TopLevelElementName.Value, dataContract.TopLevelElementNamespace.Value), 
                    out schema) == null)
                { 
                    XmlSchemaElement topLevelElement = ExportTopLevelElement(dataContract, schema); 
                    topLevelElement.IsNillable = dataContract.IsTopLevelElementNullable;
                    ReprocessAll(schemas); 
                }

                XmlSchemaType anonymousType = xsdType;
                xsdType = SchemaHelper.GetSchemaType(schemas, typeQName, out schema); 
                if (anonymousType == null && xsdType == null && typeQName.Namespace != XmlSchema.Namespace)
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeQName, DataContract.GetClrTypeFullName(clrType)))); 
                }
                if (xsdType != null) 
                    xsdType.Annotation = GetSchemaAnnotation(
                                           ExportSurrogateData(dataContract),
                                           dataContract.IsValueType ?
                                             GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema) : 
                                             null
                                         ); 
                else if (DiagnosticUtility.ShouldTraceVerbose) 
                {
                    TraceUtility.Trace(TraceEventType.Verbose, TraceCode.XsdExportAnnotationFailed, 
                        SR.GetString(SR.TraceCodeXsdExportAnnotationFailed), new StringTraceRecord("Type", typeQName.Namespace + ":" + typeQName.Name));
                }
            }
        } 

        static void ReprocessAll(XmlSchemaSet schemas)// and remove duplicate items 
        { 
            Hashtable elements = new Hashtable();
            Hashtable types = new Hashtable(); 
            XmlSchema[] schemaArray = new XmlSchema[schemas.Count];
            schemas.CopyTo(schemaArray, 0);
            for (int i=0;i values = new Dictionary(2)
                            { 
                                { "ItemType", item.ToString() },
                                { "Name", qname.Namespace + ":" + qname.Name } 
                            }; 
                            TraceUtility.Trace(TraceEventType.Warning, TraceCode.XsdExportDupItems,
                                SR.GetString(SR.TraceCodeXsdExportDupItems), new DictionaryTraceRecord(values)); 
                        }
                       schema.Items.Remove(item);
                    }
                    else 
                        items.Add(qname, item);
                } 
                schemas.Reprocess(schema); 
            }
        } 

        internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
        {
            if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot)) 
                return;
            XmlSchemaSet schemas = new XmlSchemaSet(); 
            schemas.XmlResolver = null; 
            InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
            if (stableName.Name == null || stableName.Name.Length == 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
        }

        static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot) 
        {
            xsdType = null; 
            hasRoot = true; 
            object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
            if (attrs == null || attrs.Length == 0) 
            {
                stableName = DataContract.GetDefaultStableName(clrType);
                return false;
            } 

            XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0]; 
            if (provider.IsAny) 
            {
                xsdType = CreateAnyElementType(); 
                hasRoot = false;
            }
            string methodName = provider.MethodName;
            if (methodName == null || methodName.Length == 0) 
            {
                if (!provider.IsAny) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); 
                stableName = DataContract.GetDefaultStableName(clrType);
            } 
            else
            {
                MethodInfo getMethod = clrType.GetMethod(methodName,  /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
                if (getMethod == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
 
                if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType))) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnTypeOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName, DataContract.GetClrTypeFullName(getMethod.ReturnType), DataContract.GetClrTypeFullName(Globals.TypeOfXmlQualifiedName), typeof(XmlSchemaType))));
 
                object typeInfo = getMethod.Invoke(null, new object[] { schemas });

                if (provider.IsAny)
                { 
                    if (typeInfo != null)
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName))); 
                    stableName = DataContract.GetDefaultStableName(clrType); 
                }
                else if (typeInfo == null) 
                {
                    xsdType = CreateAnyElementType();
                    hasRoot = false;
                    stableName = DataContract.GetDefaultStableName(clrType); 
                }
                else 
                { 
                    XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
                    if (providerXsdType != null) 
                    {
                        string typeName = providerXsdType.Name;
                        string typeNs = null;
                        if (typeName == null || typeName.Length == 0) 
                        {
                            DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs); 
                            stableName = new XmlQualifiedName(typeName, typeNs); 
                            providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
                            xsdType = providerXsdType; 
                        }
                        else
                        {
                            foreach (XmlSchema schema in schemas.Schemas()) 
                            {
                                foreach (XmlSchemaObject schemaItem in schema.Items) 
                                { 
                                    if ((object)schemaItem == (object)providerXsdType)
                                    { 
                                        typeNs = schema.TargetNamespace;
                                        if (typeNs == null)
                                            typeNs = String.Empty;
                                        break; 
                                    }
                                } 
                                if (typeNs != null) 
                                    break;
                            } 
                            if (typeNs == null)
                                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
                            stableName = new XmlQualifiedName(typeName, typeNs);
                        } 
                    }
                    else 
                        stableName = (XmlQualifiedName)typeInfo; 
                }
            } 
            return true;
        }

        static void InvokeGetSchemaMethod(Type clrType, XmlSchemaSet schemas, XmlQualifiedName stableName) 
        {
            IXmlSerializable ixmlSerializable = (IXmlSerializable)Activator.CreateInstance(clrType); 
            XmlSchema schema = ixmlSerializable.GetSchema(); 
            if (schema == null)
            { 
                AddDefaultDatasetType(schemas, stableName.Name, stableName.Namespace);
            }
            else
            { 
                if (schema.Id == null || schema.Id.Length == 0)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnSchemaOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); 
                AddDefaultTypedDatasetType(schemas, schema, stableName.Name, stableName.Namespace); 
            }
        } 

        internal static void AddDefaultXmlType(XmlSchemaSet schemas, string localName, string ns)
        {
            XmlSchemaComplexType defaultXmlType = CreateAnyType(); 
            defaultXmlType.Name = localName;
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas); 
            schema.Items.Add(defaultXmlType); 
            schemas.Reprocess(schema);
        } 

        static XmlSchemaComplexType CreateAnyType()
        {
            XmlSchemaComplexType anyType = new XmlSchemaComplexType(); 
            anyType.IsMixed = true;
            anyType.Particle = new XmlSchemaSequence(); 
            XmlSchemaAny any = new XmlSchemaAny(); 
            any.MinOccurs = 0;
            any.MaxOccurs = Decimal.MaxValue; 
            any.ProcessContents = XmlSchemaContentProcessing.Lax;
            ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
            anyType.AnyAttribute = new XmlSchemaAnyAttribute();
            return anyType; 
        }
 
        static XmlSchemaComplexType CreateAnyElementType() 
        {
            XmlSchemaComplexType anyElementType = new XmlSchemaComplexType(); 
            anyElementType.IsMixed = false;
            anyElementType.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny();
            any.MinOccurs = 0; 
            any.ProcessContents = XmlSchemaContentProcessing.Lax;
            ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any); 
            return anyElementType; 
        }
 
        internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
        {
            xsdType = null;
            hasRoot = true; 
            if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
            { 
                string name = null; 
                if (type == Globals.TypeOfXmlElement)
                { 
                    xsdType = CreateAnyElementType();
                    name = "XmlElement";
                    hasRoot = false;
                } 
                else
                { 
                    xsdType = CreateAnyType(); 
                    name = "ArrayOfXmlNode";
                    hasRoot = true; 
                }
                typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
                return true;
            } 
            typeName = null;
            return false; 
        } 

        static void AddDefaultDatasetType(XmlSchemaSet schemas, string localName, string ns) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = localName;
            type.Particle = new XmlSchemaSequence(); 
            XmlSchemaElement schemaRefElement = new XmlSchemaElement();
            schemaRefElement.RefName = new XmlQualifiedName(Globals.SchemaLocalName, XmlSchema.Namespace); 
            ((XmlSchemaSequence)type.Particle).Items.Add(schemaRefElement); 
            XmlSchemaAny any = new XmlSchemaAny();
            ((XmlSchemaSequence)type.Particle).Items.Add(any); 
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas);
            schema.Items.Add(type);
            schemas.Reprocess(schema);
        } 

        static void AddDefaultTypedDatasetType(XmlSchemaSet schemas, XmlSchema datasetSchema, string localName, string ns) 
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = localName; 
            type.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny();
            any.Namespace = (datasetSchema.TargetNamespace == null) ? String.Empty : datasetSchema.TargetNamespace;
            ((XmlSchemaSequence)type.Particle).Items.Add(any); 
            schemas.Add(datasetSchema);
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas); 
            schema.Items.Add(type); 
            schemas.Reprocess(datasetSchema);
            schemas.Reprocess(schema); 
        }

        XmlSchemaAnnotation GetSchemaAnnotation(XmlQualifiedName annotationQualifiedName, string innerText, XmlSchema schema)
        { 
            XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
            XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo(); 
            XmlElement annotationElement = GetAnnotationMarkup(annotationQualifiedName, innerText, schema); 
            appInfo.Markup = new XmlNode[1] { annotationElement };
            annotation.Items.Add(appInfo); 
            return annotation;
        }

        static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes) 
        {
            if (nodes == null || nodes.Length == 0) 
                return null; 
            bool hasAnnotation = false;
            for (int i=0;i pair in dataContractSet)
                {
                    DataContract dataContract = pair.Value;
                    if (!dataContractSet.IsContractProcessed(dataContract)) 
                    {
                        ExportDataContract(dataContract); 
                        dataContractSet.SetContractProcessed(dataContract); 
                    }
                } 
            }
            finally
            {
                xmlDoc = null; 
                dataContractSet = null;
            } 
        } 

        void ExportSerializationSchema() 
        {
            if (!Schemas.Contains(Globals.SerializationNamespace))
            {
                StringReader reader = new StringReader(Globals.SerializationSchema); 
                XmlSchema schema = XmlSchema.Read(reader, null);
                if (schema == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CouldNotReadSerializationSchema, Globals.SerializationNamespace))); 
                Schemas.Add(schema);
            } 
        }

        void ExportDataContract(DataContract dataContract)
        { 
            if (dataContract.IsBuiltInDataContract)
                return; 
            else if (dataContract is XmlDataContract) 
                ExportXmlDataContract((XmlDataContract)dataContract);
            else 
            {
                XmlSchema schema = GetSchema(dataContract.StableName.Namespace);

                if (dataContract is ClassDataContract) 
                {
                    ClassDataContract classDataContract = (ClassDataContract)dataContract; 
                    if (classDataContract.IsISerializable) 
                        ExportISerializableDataContract(classDataContract, schema);
                    else 
                        ExportClassDataContract(classDataContract, schema);
                }
                else if (dataContract is CollectionDataContract)
                    ExportCollectionDataContract((CollectionDataContract)dataContract, schema); 
                else if (dataContract is EnumDataContract)
                    ExportEnumDataContract((EnumDataContract)dataContract, schema); 
                ExportTopLevelElement(dataContract, schema); 
                Schemas.Reprocess(schema);
            } 
        }

        XmlSchemaElement ExportTopLevelElement(DataContract dataContract, XmlSchema schema)
        { 
            if (schema == null || dataContract.StableName.Namespace != dataContract.TopLevelElementNamespace.Value)
                schema = GetSchema(dataContract.TopLevelElementNamespace.Value); 
 
            XmlSchemaElement topLevelElement = new XmlSchemaElement();
            topLevelElement.Name = dataContract.TopLevelElementName.Value; 
            SetElementType(topLevelElement, dataContract, schema);
            topLevelElement.IsNillable = true;
            schema.Items.Add(topLevelElement);
            return topLevelElement; 
        }
 
        void ExportClassDataContract(ClassDataContract classDataContract, XmlSchema schema) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType(); 
            type.Name = classDataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null;
            if (classDataContract.UnderlyingType.IsGenericType) 
                genericInfoElement = ExportGenericInfo(classDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace);
 
            XmlSchemaSequence rootSequence = new XmlSchemaSequence(); 
            for (int i=0; i < classDataContract.Members.Count; i++)
            { 
                DataMember dataMember = classDataContract.Members[i];

                XmlSchemaElement element = new XmlSchemaElement();
                element.Name = dataMember.Name; 
                XmlElement actualTypeElement=null;
                DataContract memberTypeContract = dataContractSet.GetMemberTypeDataContract(dataMember); 
                if (CheckIfMemberHasConflict(dataMember)) 
                {
                    element.SchemaTypeName = AnytypeQualifiedName; 
                    actualTypeElement = ExportActualType(memberTypeContract.StableName);
                    SchemaHelper.AddSchemaImport(memberTypeContract.StableName.Namespace, schema);
                }
                else 
                    SetElementType(element, memberTypeContract, schema);
                SchemaHelper.AddElementForm(element, schema); 
                if (dataMember.IsNullable) 
                    element.IsNillable = true;
                if (!dataMember.IsRequired) 
                    element.MinOccurs = 0;

                element.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(dataMember), ExportEmitDefaultValue(dataMember));
                rootSequence.Items.Add(element); 
            }
 
            XmlElement isValueTypeElement = null; 
            if (classDataContract.BaseContract != null)
            { 
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, classDataContract.BaseContract.StableName, schema);
                extension.Particle = rootSequence;
                if (classDataContract.IsReference && !classDataContract.BaseContract.IsReference)
                { 
                    AddReferenceAttributes(extension.Attributes, schema);
                } 
            } 
            else
            { 
                type.Particle = rootSequence;
                if (classDataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(classDataContract.IsValueType), schema);
                if (classDataContract.IsReference) 
                    AddReferenceAttributes(type.Attributes, schema);
            } 
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(classDataContract), isValueTypeElement); 
        }
 
        void AddReferenceAttributes(XmlSchemaObjectCollection attributes, XmlSchema schema)
        {
            SchemaHelper.AddSchemaImport(Globals.SerializationNamespace, schema);
            schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace); 
            attributes.Add(IdAttribute);
            attributes.Add(RefAttribute); 
        } 

        void SetElementType(XmlSchemaElement element, DataContract dataContract, XmlSchema schema) 
        {
            XmlDataContract xmlDataContract = dataContract as XmlDataContract;
            if (xmlDataContract != null && xmlDataContract.IsAnonymous)
            { 
                element.SchemaType = xmlDataContract.XsdType;
            } 
            else 
            {
                element.SchemaTypeName = dataContract.StableName; 

                if (element.SchemaTypeName.Namespace.Equals(Globals.SerializationNamespace))
                    schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace);
 
                SchemaHelper.AddSchemaImport(dataContract.StableName.Namespace, schema);
            } 
        } 

        bool CheckIfMemberHasConflict(DataMember dataMember) 
        {
            if (dataMember.HasConflictingNameAndType)
                return true;
 
            DataMember conflictingMember = dataMember.ConflictingMember;
            while (conflictingMember != null) 
            { 
                if (conflictingMember.HasConflictingNameAndType)
                    return true; 
                conflictingMember = conflictingMember.ConflictingMember;
            }

            return false; 
        }
 
        private XmlElement ExportEmitDefaultValue(DataMember dataMember) 
        {
            if (dataMember.EmitDefaultValue) 
                return null;
            XmlElement defaultValueElement = XmlDoc.CreateElement(DefaultValueAnnotation.Name, DefaultValueAnnotation.Namespace);
            XmlAttribute emitDefaultValueAttribute = XmlDoc.CreateAttribute(Globals.EmitDefaultValueAttribute);
            emitDefaultValueAttribute.Value = Globals.False; 
            defaultValueElement.Attributes.Append(emitDefaultValueAttribute);
            return defaultValueElement; 
 
        }
 
        XmlElement ExportActualType(XmlQualifiedName typeName)
        {
            return ExportActualType(typeName, XmlDoc);
        } 

        static XmlElement ExportActualType(XmlQualifiedName typeName, XmlDocument xmlDoc) 
        { 
            XmlElement actualTypeElement = xmlDoc.CreateElement(ActualTypeAnnotationName.Name, ActualTypeAnnotationName.Namespace);
 
            XmlAttribute nameAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNameAttribute);
            nameAttribute.Value = typeName.Name;
            actualTypeElement.Attributes.Append(nameAttribute);
 
            XmlAttribute nsAttribute = xmlDoc.CreateAttribute(Globals.ActualTypeNamespaceAttribute);
            nsAttribute.Value = typeName.Namespace; 
            actualTypeElement.Attributes.Append(nsAttribute); 

            return actualTypeElement; 
        }

        XmlElement ExportGenericInfo(Type clrType, string elementName, string elementNs)
        { 
            Type itemType;
            int nestedCollectionLevel = 0; 
            while (CollectionDataContract.IsCollection(clrType, out itemType)) 
            {
                if (DataContract.GetBuiltInDataContract(clrType) != null 
                    || CollectionDataContract.IsCollectionDataContract(clrType))
                {
                    break;
                } 
                clrType = itemType;
                nestedCollectionLevel++; 
            } 

            Type[] genericArguments = null; 
            IList genericArgumentCounts = null;
            if (clrType.IsGenericType)
            {
                genericArguments = clrType.GetGenericArguments(); 
                string typeName;
                if (clrType.DeclaringType == null) 
                    typeName = clrType.Name; 
                else
                { 
                    int nsLen = (clrType.Namespace == null) ? 0 : clrType.Namespace.Length;
                    if (nsLen > 0)
                        nsLen++; //include the . following namespace
                    typeName = DataContract.GetClrTypeFullName(clrType).Substring(nsLen).Replace('+', '.'); 
                }
                int iParam = typeName.IndexOf('['); 
                if (iParam >= 0) 
                    typeName = typeName.Substring(0, iParam);
                genericArgumentCounts = DataContract.GetDataContractNameForGenericName(typeName, null); 
                clrType = clrType.GetGenericTypeDefinition();
            }
            XmlQualifiedName dcqname = DataContract.GetStableName(clrType);
            if (nestedCollectionLevel > 0) 
            {
                string collectionName = dcqname.Name; 
                for (int n = 0; n < nestedCollectionLevel; n++) 
                    collectionName = Globals.ArrayPrefix + collectionName;
                dcqname = new XmlQualifiedName(collectionName, DataContract.GetCollectionNamespace(dcqname.Namespace)); 
            }
            XmlElement typeElement = XmlDoc.CreateElement(elementName, elementNs);

            XmlAttribute nameAttribute = XmlDoc.CreateAttribute(Globals.GenericNameAttribute); 
            nameAttribute.Value = genericArguments != null ? XmlConvert.DecodeName(dcqname.Name) : dcqname.Name;
            //nameAttribute.Value = dcqname.Name; 
            typeElement.Attributes.Append(nameAttribute); 

            XmlAttribute nsAttribute = XmlDoc.CreateAttribute(Globals.GenericNamespaceAttribute); 
            nsAttribute.Value = dcqname.Namespace;
            typeElement.Attributes.Append(nsAttribute);

            if (genericArguments != null) 
            {
                int argIndex = 0; 
                int nestedLevel = 0; 
                foreach (int genericArgumentCount in genericArgumentCounts)
                { 
                    for (int i = 0; i < genericArgumentCount; i++, argIndex++)
                    {
                        XmlElement argumentElement = ExportGenericInfo(genericArguments[argIndex], Globals.GenericParameterLocalName, Globals.SerializationNamespace);
                        if (nestedLevel > 0) 
                        {
                            XmlAttribute nestedLevelAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute); 
                            nestedLevelAttribute.Value = nestedLevel.ToString(CultureInfo.InvariantCulture); 
                            argumentElement.Attributes.Append(nestedLevelAttribute);
                        } 
                        typeElement.AppendChild(argumentElement);
                    }
                    nestedLevel++;
                } 
                if (genericArgumentCounts[nestedLevel - 1] == 0)
                { 
                    XmlAttribute typeNestedLevelsAttribute = XmlDoc.CreateAttribute(Globals.GenericParameterNestedLevelAttribute); 
                    typeNestedLevelsAttribute.Value = genericArgumentCounts.Count.ToString(CultureInfo.InvariantCulture);
                    typeElement.Attributes.Append(typeNestedLevelsAttribute); 
                }
            }

            return typeElement; 
        }
 
        XmlElement ExportSurrogateData(object key) 
        {
            object surrogateData = dataContractSet.GetSurrogateData(key); 
            if (surrogateData == null)
                return null;
            StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
            XmlWriterSettings writerSettings = new XmlWriterSettings(); 
            writerSettings.OmitXmlDeclaration = true;
            XmlWriter xmlWriter = XmlWriter.Create(stringWriter, writerSettings); 
            Collection knownTypes = new Collection(); 
            DataContractSurrogateCaller.GetKnownCustomDataTypes(dataContractSet.DataContractSurrogate, knownTypes);
            DataContractSerializer serializer = new DataContractSerializer(Globals.TypeOfObject, 
                SurrogateDataAnnotationName.Name, SurrogateDataAnnotationName.Namespace, knownTypes, Int32.MaxValue,
                false /*ignoreExtensionDataObject*/, true /*preserveObjectReferences*/, null /*dataContractSurrogate*/);
            serializer.WriteObject(xmlWriter, surrogateData);
            xmlWriter.Flush(); 
            return (XmlElement)XmlDoc.ReadNode(XmlReader.Create(new StringReader(stringWriter.ToString())));
        } 
 
        void ExportCollectionDataContract(CollectionDataContract collectionDataContract, XmlSchema schema)
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = collectionDataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null, isDictionaryElement = null; 
            if (collectionDataContract.UnderlyingType.IsGenericType && CollectionDataContract.IsCollectionDataContract(collectionDataContract.UnderlyingType))
                genericInfoElement = ExportGenericInfo(collectionDataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace); 
            if (collectionDataContract.IsDictionary) 
                isDictionaryElement = ExportIsDictionary();
            type.Annotation = GetSchemaAnnotation(isDictionaryElement, genericInfoElement, ExportSurrogateData(collectionDataContract)); 

            XmlSchemaSequence rootSequence = new XmlSchemaSequence();

            XmlSchemaElement element = new XmlSchemaElement(); 
            element.Name = collectionDataContract.ItemName;
            element.MinOccurs = 0; 
            element.MaxOccursString = Globals.OccursUnbounded; 
            if (collectionDataContract.IsDictionary)
            { 
                ClassDataContract keyValueContract = collectionDataContract.ItemContract as ClassDataContract;
                XmlSchemaComplexType keyValueType = new XmlSchemaComplexType();
                XmlSchemaSequence keyValueSequence = new XmlSchemaSequence();
                foreach (DataMember dataMember in keyValueContract.Members) 
                {
                    XmlSchemaElement keyValueElement = new XmlSchemaElement(); 
                    keyValueElement.Name = dataMember.Name; 
                    SetElementType(keyValueElement, dataContractSet.GetMemberTypeDataContract(dataMember), schema);
                    SchemaHelper.AddElementForm(keyValueElement, schema); 
                    if (dataMember.IsNullable)
                        keyValueElement.IsNillable = true;
                    keyValueElement.Annotation = GetSchemaAnnotation(ExportSurrogateData(dataMember));
                    keyValueSequence.Items.Add(keyValueElement); 
                }
                keyValueType.Particle = keyValueSequence; 
                element.SchemaType = keyValueType; 
            }
            else 
            {
                if (collectionDataContract.IsItemTypeNullable)
                    element.IsNillable = true;
                DataContract itemContract = dataContractSet.GetItemTypeDataContract(collectionDataContract); 
                SetElementType(element, itemContract, schema);
            } 
            SchemaHelper.AddElementForm(element, schema); 
            rootSequence.Items.Add(element);
 
            type.Particle = rootSequence;

            if (collectionDataContract.IsReference)
                AddReferenceAttributes(type.Attributes, schema); 
        }
 
        XmlElement ExportIsDictionary() 
        {
            XmlElement isDictionaryElement = XmlDoc.CreateElement(IsDictionaryAnnotationName.Name, IsDictionaryAnnotationName.Namespace); 
            isDictionaryElement.InnerText = Globals.True;
            return isDictionaryElement;
        }
 
        void ExportEnumDataContract(EnumDataContract enumDataContract, XmlSchema schema)
        { 
            XmlSchemaSimpleType type = new XmlSchemaSimpleType(); 
            type.Name = enumDataContract.StableName.Name;
            XmlElement actualTypeElement = (enumDataContract.BaseContractName == DefaultEnumBaseTypeName) ? null : ExportActualType(enumDataContract.BaseContractName); 
            type.Annotation = GetSchemaAnnotation(actualTypeElement, ExportSurrogateData(enumDataContract));
            schema.Items.Add(type);

            XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction(); 
            restriction.BaseTypeName = StringQualifiedName;
            SchemaHelper.AddSchemaImport(enumDataContract.BaseContractName.Namespace, schema); 
            if (enumDataContract.Values != null) 
            {
                for (int i = 0; i < enumDataContract.Values.Count; i++) 
                {
                    XmlSchemaEnumerationFacet facet = new XmlSchemaEnumerationFacet();
                    facet.Value = enumDataContract.Members[i].Name;
                    if (enumDataContract.Values[i] != GetDefaultEnumValue(enumDataContract.IsFlags, i)) 
                        facet.Annotation = GetSchemaAnnotation(EnumerationValueAnnotationName, enumDataContract.GetStringFromEnumValue(enumDataContract.Values[i]), schema);
                    restriction.Facets.Add(facet); 
                } 
            }
            if (enumDataContract.IsFlags) 
            {
                XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                XmlSchemaSimpleType anonymousType = new XmlSchemaSimpleType();
                anonymousType.Content = restriction; 
                list.ItemType = anonymousType;
                type.Content = list; 
            } 
            else
                type.Content = restriction; 
        }

        internal static long GetDefaultEnumValue(bool isFlags, int index)
        { 
            return isFlags ? (long)Math.Pow(2, index) : index;
        } 
 
        void ExportISerializableDataContract(ClassDataContract dataContract, XmlSchema schema)
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = dataContract.StableName.Name;
            schema.Items.Add(type);
            XmlElement genericInfoElement = null; 
            if (dataContract.UnderlyingType.IsGenericType)
                genericInfoElement = ExportGenericInfo(dataContract.UnderlyingType, Globals.GenericTypeLocalName, Globals.SerializationNamespace); 
 
            XmlElement isValueTypeElement = null;
            if (dataContract.BaseContract != null) 
            {
                XmlSchemaComplexContentExtension extension = CreateTypeContent(type, dataContract.BaseContract.StableName, schema);
            }
            else 
            {
                schema.Namespaces.Add(Globals.SerPrefixForSchema, Globals.SerializationNamespace); 
                type.Particle = ISerializableSequence; 
                XmlSchemaAttribute iSerializableFactoryTypeAttribute = ISerializableFactoryTypeAttribute;
                type.Attributes.Add(iSerializableFactoryTypeAttribute); 
                SchemaHelper.AddSchemaImport(ISerializableFactoryTypeAttribute.RefName.Namespace, schema);
                if (dataContract.IsValueType)
                    isValueTypeElement = GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema);
            } 
            type.Annotation = GetSchemaAnnotation(genericInfoElement, ExportSurrogateData(dataContract), isValueTypeElement);
        } 
 
        XmlSchemaComplexContentExtension CreateTypeContent(XmlSchemaComplexType type, XmlQualifiedName baseTypeName, XmlSchema schema)
        { 
            SchemaHelper.AddSchemaImport(baseTypeName.Namespace, schema);

            XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
            extension.BaseTypeName = baseTypeName; 
            type.ContentModel = new XmlSchemaComplexContent();
            type.ContentModel.Content = extension; 
 
            return extension;
        } 

        void ExportXmlDataContract(XmlDataContract dataContract)
        {
            XmlQualifiedName typeQName; 
            bool hasRoot;
            XmlSchemaType xsdType; 
 
            Type clrType = dataContract.UnderlyingType;
            if (!IsSpecialXmlType(clrType, out typeQName, out xsdType, out hasRoot)) 
                if (!InvokeSchemaProviderMethod(clrType, schemas, out typeQName, out xsdType, out hasRoot))
                    InvokeGetSchemaMethod(clrType, schemas, typeQName);

            if (hasRoot) 
            {
                if (!(typeQName.Equals(dataContract.StableName))) 
                { 
                    Fx.Assert("XML data contract type name does not match schema name");
                } 

                XmlSchema schema;
                if (SchemaHelper.GetSchemaElement(Schemas,
                    new XmlQualifiedName(dataContract.TopLevelElementName.Value, dataContract.TopLevelElementNamespace.Value), 
                    out schema) == null)
                { 
                    XmlSchemaElement topLevelElement = ExportTopLevelElement(dataContract, schema); 
                    topLevelElement.IsNillable = dataContract.IsTopLevelElementNullable;
                    ReprocessAll(schemas); 
                }

                XmlSchemaType anonymousType = xsdType;
                xsdType = SchemaHelper.GetSchemaType(schemas, typeQName, out schema); 
                if (anonymousType == null && xsdType == null && typeQName.Namespace != XmlSchema.Namespace)
                { 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeQName, DataContract.GetClrTypeFullName(clrType)))); 
                }
                if (xsdType != null) 
                    xsdType.Annotation = GetSchemaAnnotation(
                                           ExportSurrogateData(dataContract),
                                           dataContract.IsValueType ?
                                             GetAnnotationMarkup(IsValueTypeName, XmlConvert.ToString(dataContract.IsValueType), schema) : 
                                             null
                                         ); 
                else if (DiagnosticUtility.ShouldTraceVerbose) 
                {
                    TraceUtility.Trace(TraceEventType.Verbose, TraceCode.XsdExportAnnotationFailed, 
                        SR.GetString(SR.TraceCodeXsdExportAnnotationFailed), new StringTraceRecord("Type", typeQName.Namespace + ":" + typeQName.Name));
                }
            }
        } 

        static void ReprocessAll(XmlSchemaSet schemas)// and remove duplicate items 
        { 
            Hashtable elements = new Hashtable();
            Hashtable types = new Hashtable(); 
            XmlSchema[] schemaArray = new XmlSchema[schemas.Count];
            schemas.CopyTo(schemaArray, 0);
            for (int i=0;i values = new Dictionary(2)
                            { 
                                { "ItemType", item.ToString() },
                                { "Name", qname.Namespace + ":" + qname.Name } 
                            }; 
                            TraceUtility.Trace(TraceEventType.Warning, TraceCode.XsdExportDupItems,
                                SR.GetString(SR.TraceCodeXsdExportDupItems), new DictionaryTraceRecord(values)); 
                        }
                       schema.Items.Remove(item);
                    }
                    else 
                        items.Add(qname, item);
                } 
                schemas.Reprocess(schema); 
            }
        } 

        internal static void GetXmlTypeInfo(Type type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot)
        {
            if (IsSpecialXmlType(type, out stableName, out xsdType, out hasRoot)) 
                return;
            XmlSchemaSet schemas = new XmlSchemaSet(); 
            schemas.XmlResolver = null; 
            InvokeSchemaProviderMethod(type, schemas, out stableName, out xsdType, out hasRoot);
            if (stableName.Name == null || stableName.Name.Length == 0) 
                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidXmlDataContractName, DataContract.GetClrTypeFullName(type))));
        }

        static bool InvokeSchemaProviderMethod(Type clrType, XmlSchemaSet schemas, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot) 
        {
            xsdType = null; 
            hasRoot = true; 
            object[] attrs = clrType.GetCustomAttributes(Globals.TypeOfXmlSchemaProviderAttribute, false);
            if (attrs == null || attrs.Length == 0) 
            {
                stableName = DataContract.GetDefaultStableName(clrType);
                return false;
            } 

            XmlSchemaProviderAttribute provider = (XmlSchemaProviderAttribute)attrs[0]; 
            if (provider.IsAny) 
            {
                xsdType = CreateAnyElementType(); 
                hasRoot = false;
            }
            string methodName = provider.MethodName;
            if (methodName == null || methodName.Length == 0) 
            {
                if (!provider.IsAny) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); 
                stableName = DataContract.GetDefaultStableName(clrType);
            } 
            else
            {
                MethodInfo getMethod = clrType.GetMethod(methodName,  /*BindingFlags.DeclaredOnly |*/ BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, new Type[] { typeof(XmlSchemaSet) }, null);
                if (getMethod == null) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName)));
 
                if (!(Globals.TypeOfXmlQualifiedName.IsAssignableFrom(getMethod.ReturnType)) && !(Globals.TypeOfXmlSchemaType.IsAssignableFrom(getMethod.ReturnType))) 
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnTypeOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType), methodName, DataContract.GetClrTypeFullName(getMethod.ReturnType), DataContract.GetClrTypeFullName(Globals.TypeOfXmlQualifiedName), typeof(XmlSchemaType))));
 
                object typeInfo = getMethod.Invoke(null, new object[] { schemas });

                if (provider.IsAny)
                { 
                    if (typeInfo != null)
                        throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidNonNullReturnValueByIsAny, DataContract.GetClrTypeFullName(clrType), methodName))); 
                    stableName = DataContract.GetDefaultStableName(clrType); 
                }
                else if (typeInfo == null) 
                {
                    xsdType = CreateAnyElementType();
                    hasRoot = false;
                    stableName = DataContract.GetDefaultStableName(clrType); 
                }
                else 
                { 
                    XmlSchemaType providerXsdType = typeInfo as XmlSchemaType;
                    if (providerXsdType != null) 
                    {
                        string typeName = providerXsdType.Name;
                        string typeNs = null;
                        if (typeName == null || typeName.Length == 0) 
                        {
                            DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(clrType), out typeName, out typeNs); 
                            stableName = new XmlQualifiedName(typeName, typeNs); 
                            providerXsdType.Annotation = GetSchemaAnnotation(ExportActualType(stableName, new XmlDocument()));
                            xsdType = providerXsdType; 
                        }
                        else
                        {
                            foreach (XmlSchema schema in schemas.Schemas()) 
                            {
                                foreach (XmlSchemaObject schemaItem in schema.Items) 
                                { 
                                    if ((object)schemaItem == (object)providerXsdType)
                                    { 
                                        typeNs = schema.TargetNamespace;
                                        if (typeNs == null)
                                            typeNs = String.Empty;
                                        break; 
                                    }
                                } 
                                if (typeNs != null) 
                                    break;
                            } 
                            if (typeNs == null)
                                throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.MissingSchemaType, typeName, DataContract.GetClrTypeFullName(clrType))));
                            stableName = new XmlQualifiedName(typeName, typeNs);
                        } 
                    }
                    else 
                        stableName = (XmlQualifiedName)typeInfo; 
                }
            } 
            return true;
        }

        static void InvokeGetSchemaMethod(Type clrType, XmlSchemaSet schemas, XmlQualifiedName stableName) 
        {
            IXmlSerializable ixmlSerializable = (IXmlSerializable)Activator.CreateInstance(clrType); 
            XmlSchema schema = ixmlSerializable.GetSchema(); 
            if (schema == null)
            { 
                AddDefaultDatasetType(schemas, stableName.Name, stableName.Namespace);
            }
            else
            { 
                if (schema.Id == null || schema.Id.Length == 0)
                    throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidReturnSchemaOnGetSchemaMethod, DataContract.GetClrTypeFullName(clrType)))); 
                AddDefaultTypedDatasetType(schemas, schema, stableName.Name, stableName.Namespace); 
            }
        } 

        internal static void AddDefaultXmlType(XmlSchemaSet schemas, string localName, string ns)
        {
            XmlSchemaComplexType defaultXmlType = CreateAnyType(); 
            defaultXmlType.Name = localName;
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas); 
            schema.Items.Add(defaultXmlType); 
            schemas.Reprocess(schema);
        } 

        static XmlSchemaComplexType CreateAnyType()
        {
            XmlSchemaComplexType anyType = new XmlSchemaComplexType(); 
            anyType.IsMixed = true;
            anyType.Particle = new XmlSchemaSequence(); 
            XmlSchemaAny any = new XmlSchemaAny(); 
            any.MinOccurs = 0;
            any.MaxOccurs = Decimal.MaxValue; 
            any.ProcessContents = XmlSchemaContentProcessing.Lax;
            ((XmlSchemaSequence)anyType.Particle).Items.Add(any);
            anyType.AnyAttribute = new XmlSchemaAnyAttribute();
            return anyType; 
        }
 
        static XmlSchemaComplexType CreateAnyElementType() 
        {
            XmlSchemaComplexType anyElementType = new XmlSchemaComplexType(); 
            anyElementType.IsMixed = false;
            anyElementType.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny();
            any.MinOccurs = 0; 
            any.ProcessContents = XmlSchemaContentProcessing.Lax;
            ((XmlSchemaSequence)anyElementType.Particle).Items.Add(any); 
            return anyElementType; 
        }
 
        internal static bool IsSpecialXmlType(Type type, out XmlQualifiedName typeName, out XmlSchemaType xsdType, out bool hasRoot)
        {
            xsdType = null;
            hasRoot = true; 
            if (type == Globals.TypeOfXmlElement || type == Globals.TypeOfXmlNodeArray)
            { 
                string name = null; 
                if (type == Globals.TypeOfXmlElement)
                { 
                    xsdType = CreateAnyElementType();
                    name = "XmlElement";
                    hasRoot = false;
                } 
                else
                { 
                    xsdType = CreateAnyType(); 
                    name = "ArrayOfXmlNode";
                    hasRoot = true; 
                }
                typeName = new XmlQualifiedName(name, DataContract.GetDefaultStableNamespace(type));
                return true;
            } 
            typeName = null;
            return false; 
        } 

        static void AddDefaultDatasetType(XmlSchemaSet schemas, string localName, string ns) 
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = localName;
            type.Particle = new XmlSchemaSequence(); 
            XmlSchemaElement schemaRefElement = new XmlSchemaElement();
            schemaRefElement.RefName = new XmlQualifiedName(Globals.SchemaLocalName, XmlSchema.Namespace); 
            ((XmlSchemaSequence)type.Particle).Items.Add(schemaRefElement); 
            XmlSchemaAny any = new XmlSchemaAny();
            ((XmlSchemaSequence)type.Particle).Items.Add(any); 
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas);
            schema.Items.Add(type);
            schemas.Reprocess(schema);
        } 

        static void AddDefaultTypedDatasetType(XmlSchemaSet schemas, XmlSchema datasetSchema, string localName, string ns) 
        { 
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            type.Name = localName; 
            type.Particle = new XmlSchemaSequence();
            XmlSchemaAny any = new XmlSchemaAny();
            any.Namespace = (datasetSchema.TargetNamespace == null) ? String.Empty : datasetSchema.TargetNamespace;
            ((XmlSchemaSequence)type.Particle).Items.Add(any); 
            schemas.Add(datasetSchema);
            XmlSchema schema = SchemaHelper.GetSchema(ns, schemas); 
            schema.Items.Add(type); 
            schemas.Reprocess(datasetSchema);
            schemas.Reprocess(schema); 
        }

        XmlSchemaAnnotation GetSchemaAnnotation(XmlQualifiedName annotationQualifiedName, string innerText, XmlSchema schema)
        { 
            XmlSchemaAnnotation annotation = new XmlSchemaAnnotation();
            XmlSchemaAppInfo appInfo = new XmlSchemaAppInfo(); 
            XmlElement annotationElement = GetAnnotationMarkup(annotationQualifiedName, innerText, schema); 
            appInfo.Markup = new XmlNode[1] { annotationElement };
            annotation.Items.Add(appInfo); 
            return annotation;
        }

        static XmlSchemaAnnotation GetSchemaAnnotation(params XmlNode[] nodes) 
        {
            if (nodes == null || nodes.Length == 0) 
                return null; 
            bool hasAnnotation = false;
            for (int i=0;i

                        

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