| 
									
										
										
										
											2016-08-03 10:59:49 +00:00
										 |  |  | //------------------------------------------------------------------------------ | 
					
						
							|  |  |  | // <copyright file="SoapSchemaExporter.cs" company="Microsoft"> | 
					
						
							|  |  |  | //     Copyright (c) Microsoft Corporation.  All rights reserved. | 
					
						
							|  |  |  | // </copyright> | 
					
						
							| 
									
										
										
										
											2017-08-21 15:34:15 +00:00
										 |  |  | // <owner current="true" primary="true">Microsoft</owner>                                                                 | 
					
						
							| 
									
										
										
										
											2016-08-03 10:59:49 +00:00
										 |  |  | //------------------------------------------------------------------------------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace System.Xml.Serialization { | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     using System; | 
					
						
							|  |  |  |     using System.Collections; | 
					
						
							|  |  |  |     using System.Xml.Schema; | 
					
						
							|  |  |  |     using System.Xml; | 
					
						
							|  |  |  |     using System.ComponentModel; | 
					
						
							|  |  |  |     using System.Diagnostics; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter"]/*' /> | 
					
						
							|  |  |  |     /// <internalonly/> | 
					
						
							|  |  |  |     public class SoapSchemaExporter { | 
					
						
							|  |  |  |         internal const XmlSchemaForm elementFormDefault = XmlSchemaForm.Qualified; | 
					
						
							|  |  |  |         XmlSchemas schemas; | 
					
						
							|  |  |  |         Hashtable types = new Hashtable();      // StructMapping/EnumMapping -> XmlSchemaComplexType/XmlSchemaSimpleType | 
					
						
							|  |  |  |         bool exportedRoot; | 
					
						
							|  |  |  |         TypeScope scope; | 
					
						
							|  |  |  |         XmlDocument document; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         static XmlQualifiedName ArrayQName = new XmlQualifiedName(Soap.Array, Soap.Encoding); | 
					
						
							|  |  |  |         static XmlQualifiedName ArrayTypeQName = new XmlQualifiedName(Soap.ArrayType, Soap.Encoding); | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |         /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.SoapSchemaExporter"]/*' /> | 
					
						
							|  |  |  |         /// <devdoc> | 
					
						
							|  |  |  |         ///    <para>[To be supplied.]</para> | 
					
						
							|  |  |  |         /// </devdoc> | 
					
						
							|  |  |  |         public SoapSchemaExporter(XmlSchemas schemas) { | 
					
						
							|  |  |  |             this.schemas = schemas; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportTypeMapping"]/*' /> | 
					
						
							|  |  |  |         /// <devdoc> | 
					
						
							|  |  |  |         ///    <para>[To be supplied.]</para> | 
					
						
							|  |  |  |         /// </devdoc> | 
					
						
							|  |  |  |         public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping) { | 
					
						
							|  |  |  |             CheckScope(xmlTypeMapping.Scope); | 
					
						
							|  |  |  |             ExportTypeMapping(xmlTypeMapping.Mapping, null); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportMembersMapping"]/*' /> | 
					
						
							|  |  |  |         /// <devdoc> | 
					
						
							|  |  |  |         ///    <para>[To be supplied.]</para> | 
					
						
							|  |  |  |         /// </devdoc> | 
					
						
							|  |  |  |         public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping) { | 
					
						
							|  |  |  |             ExportMembersMapping(xmlMembersMapping, false); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportMembersMapping1"]/*' /> | 
					
						
							|  |  |  |         /// <devdoc> | 
					
						
							|  |  |  |         ///    <para>[To be supplied.]</para> | 
					
						
							|  |  |  |         /// </devdoc> | 
					
						
							|  |  |  |         public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping, bool exportEnclosingType) { | 
					
						
							|  |  |  |             CheckScope(xmlMembersMapping.Scope); | 
					
						
							|  |  |  |             MembersMapping membersMapping = (MembersMapping)xmlMembersMapping.Accessor.Mapping; | 
					
						
							|  |  |  |             if (exportEnclosingType) { | 
					
						
							|  |  |  |                 ExportTypeMapping(membersMapping, null); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 foreach (MemberMapping memberMapping in membersMapping.Members) { | 
					
						
							|  |  |  |                     if (memberMapping.Elements.Length > 0)  | 
					
						
							|  |  |  |                         ExportTypeMapping(memberMapping.Elements[0].Mapping, null); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void CheckScope(TypeScope scope) { | 
					
						
							|  |  |  |             if (this.scope == null) { | 
					
						
							|  |  |  |                 this.scope = scope; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (this.scope != scope) { | 
					
						
							|  |  |  |                 throw new InvalidOperationException(Res.GetString(Res.XmlMappingsScopeMismatch)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         internal XmlDocument Document { | 
					
						
							|  |  |  |             get {  | 
					
						
							|  |  |  |                 if (document == null) document = new XmlDocument(); | 
					
						
							|  |  |  |                 return document;  | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void CheckForDuplicateType(string newTypeName, string newNamespace){ | 
					
						
							|  |  |  |             XmlSchema schema = schemas[newNamespace]; | 
					
						
							|  |  |  |             if (schema != null){ | 
					
						
							|  |  |  |                 foreach (XmlSchemaObject o in schema.Items) { | 
					
						
							|  |  |  |                     XmlSchemaType type = o as XmlSchemaType; | 
					
						
							|  |  |  |                     if ( type != null && type.Name == newTypeName) | 
					
						
							|  |  |  |                         throw new InvalidOperationException(Res.GetString(Res.XmlDuplicateTypeName, newTypeName, newNamespace)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void AddSchemaItem(XmlSchemaObject item, string ns, string referencingNs) { | 
					
						
							|  |  |  |             if (!SchemaContainsItem(item, ns)) { | 
					
						
							|  |  |  |                 XmlSchema schema = schemas[ns]; | 
					
						
							|  |  |  |                 if (schema == null) { | 
					
						
							|  |  |  |                     schema = new XmlSchema(); | 
					
						
							|  |  |  |                     schema.TargetNamespace = ns == null || ns.Length == 0 ? null : ns; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma warning disable 429   // unreachable code detected:  elementFormDefault is const so it will never be Unqualified | 
					
						
							|  |  |  |                     schema.ElementFormDefault = elementFormDefault == XmlSchemaForm.Unqualified ? XmlSchemaForm.None : elementFormDefault; | 
					
						
							|  |  |  | #pragma warning restore 429 | 
					
						
							|  |  |  |                     schemas.Add(schema); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 schema.Items.Add(item); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (referencingNs != null) | 
					
						
							|  |  |  |                 AddSchemaImport(ns, referencingNs); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void AddSchemaImport(string ns, string referencingNs) { | 
					
						
							|  |  |  |             if (referencingNs == null || ns == null) return; | 
					
						
							|  |  |  |             if (ns == referencingNs) return; | 
					
						
							|  |  |  |             XmlSchema schema = schemas[referencingNs]; | 
					
						
							|  |  |  |             if (schema == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingSchema, referencingNs)); | 
					
						
							|  |  |  |             if (ns != null && ns.Length > 0 && FindImport(schema, ns) == null) { | 
					
						
							|  |  |  |                 XmlSchemaImport import = new XmlSchemaImport(); | 
					
						
							|  |  |  |                 import.Namespace = ns; | 
					
						
							|  |  |  |                 schema.Includes.Add(import); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         bool SchemaContainsItem(XmlSchemaObject item, string ns) { | 
					
						
							|  |  |  |             XmlSchema schema = schemas[ns]; | 
					
						
							|  |  |  |             if (schema != null) { | 
					
						
							|  |  |  |                 return schema.Items.Contains(item); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlSchemaImport FindImport(XmlSchema schema, string ns) { | 
					
						
							|  |  |  |             foreach (object item in schema.Includes) { | 
					
						
							|  |  |  |                 if (item is XmlSchemaImport) { | 
					
						
							|  |  |  |                     XmlSchemaImport import = (XmlSchemaImport)item; | 
					
						
							|  |  |  |                     if (import.Namespace == ns) { | 
					
						
							|  |  |  |                         return import; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportTypeMapping(TypeMapping mapping, string ns) { | 
					
						
							|  |  |  |             if (mapping is ArrayMapping) | 
					
						
							|  |  |  |                  return ExportArrayMapping((ArrayMapping)mapping, ns); | 
					
						
							|  |  |  |             else if (mapping is EnumMapping) | 
					
						
							|  |  |  |                 return ExportEnumMapping((EnumMapping)mapping, ns); | 
					
						
							|  |  |  |             else if (mapping is PrimitiveMapping) { | 
					
						
							|  |  |  |                 PrimitiveMapping pm = (PrimitiveMapping)mapping; | 
					
						
							|  |  |  |                 if (pm.TypeDesc.IsXsdType) { | 
					
						
							|  |  |  |                     return ExportPrimitiveMapping(pm); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     return ExportNonXsdPrimitiveMapping(pm, ns); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else if (mapping is StructMapping) | 
					
						
							|  |  |  |                 return ExportStructMapping((StructMapping)mapping, ns); | 
					
						
							|  |  |  |             else if (mapping is NullableMapping) | 
					
						
							|  |  |  |                 return ExportTypeMapping(((NullableMapping)mapping).BaseMapping, ns); | 
					
						
							|  |  |  |             else if (mapping is MembersMapping) | 
					
						
							|  |  |  |                 return ExportMembersMapping((MembersMapping)mapping, ns); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 throw new ArgumentException(Res.GetString(Res.XmlInternalError), "mapping"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportNonXsdPrimitiveMapping(PrimitiveMapping mapping, string ns) { | 
					
						
							|  |  |  |             XmlSchemaType type = mapping.TypeDesc.DataType; | 
					
						
							|  |  |  |             if (!SchemaContainsItem(type, UrtTypes.Namespace)) { | 
					
						
							|  |  |  |                 AddSchemaItem(type, UrtTypes.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 AddSchemaImport(UrtTypes.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, UrtTypes.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportPrimitiveMapping(PrimitiveMapping mapping) { | 
					
						
							|  |  |  |             return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, XmlSchema.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportArrayMapping(ArrayMapping mapping, string ns) { | 
					
						
							|  |  |  |             // for the Rpc ArrayMapping  different mappings could have the same schema type | 
					
						
							|  |  |  |             // we link all mappings corresponding to the same type together | 
					
						
							|  |  |  |             // loop through all mapping that will map to the same complexType, and export only one,  | 
					
						
							|  |  |  |             // the obvious choice is the last one. | 
					
						
							|  |  |  |             while (mapping.Next != null) { | 
					
						
							|  |  |  |                 mapping = mapping.Next; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping]; | 
					
						
							|  |  |  |             if (type == null) { | 
					
						
							|  |  |  |                 CheckForDuplicateType(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |                 type = new XmlSchemaComplexType(); | 
					
						
							|  |  |  |                 type.Name = mapping.TypeName; | 
					
						
							|  |  |  |                 types.Add(mapping, type); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // we need to add the type first, to make sure that the schema get created | 
					
						
							|  |  |  |                 AddSchemaItem(type, mapping.Namespace, ns); | 
					
						
							|  |  |  |                 AddSchemaImport(Soap.Encoding, mapping.Namespace); | 
					
						
							|  |  |  |                 AddSchemaImport(Wsdl.Namespace, mapping.Namespace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction(); | 
					
						
							|  |  |  |                 XmlQualifiedName qname = ExportTypeMapping(mapping.Elements[0].Mapping, mapping.Namespace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (qname.IsEmpty) { | 
					
						
							|  |  |  |                     // this is a root mapping | 
					
						
							|  |  |  |                     qname = new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 //<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:float[]"/>  | 
					
						
							|  |  |  |                 XmlSchemaAttribute attr = new XmlSchemaAttribute(); | 
					
						
							|  |  |  |                 attr.RefName = ArrayTypeQName; | 
					
						
							|  |  |  |                 XmlAttribute attribute = new XmlAttribute("wsdl", Wsdl.ArrayType, Wsdl.Namespace, Document); | 
					
						
							|  |  |  |                 attribute.Value = qname.Namespace + ":" + qname.Name + "[]"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 attr.UnhandledAttributes = new XmlAttribute[] {attribute}; | 
					
						
							|  |  |  |                 restriction.Attributes.Add(attr); | 
					
						
							|  |  |  |                 restriction.BaseTypeName = ArrayQName; | 
					
						
							|  |  |  |                 XmlSchemaComplexContent model = new XmlSchemaComplexContent(); | 
					
						
							|  |  |  |                 model.Content = restriction; | 
					
						
							|  |  |  |                 type.ContentModel = model; | 
					
						
							|  |  |  |                 if (qname.Namespace != XmlSchema.Namespace) | 
					
						
							|  |  |  |                     AddSchemaImport(qname.Namespace, mapping.Namespace); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 AddSchemaImport(mapping.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void ExportElementAccessors(XmlSchemaGroupBase group, ElementAccessor[] accessors, bool repeats, bool valueTypeOptional, string ns) { | 
					
						
							|  |  |  |             if (accessors.Length == 0) return; | 
					
						
							|  |  |  |             if (accessors.Length == 1) { | 
					
						
							|  |  |  |                 ExportElementAccessor(group, accessors[0], repeats, valueTypeOptional, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 XmlSchemaChoice choice = new XmlSchemaChoice(); | 
					
						
							|  |  |  |                 choice.MaxOccurs = repeats ? decimal.MaxValue : 1; | 
					
						
							|  |  |  |                 choice.MinOccurs = repeats ? 0 : 1; | 
					
						
							|  |  |  |                 for (int i = 0; i < accessors.Length; i++) | 
					
						
							|  |  |  |                     ExportElementAccessor(choice, accessors[i], false, valueTypeOptional, ns); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (choice.Items.Count > 0) group.Items.Add(choice); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void ExportElementAccessor(XmlSchemaGroupBase group, ElementAccessor accessor, bool repeats, bool valueTypeOptional, string ns) { | 
					
						
							|  |  |  |             XmlSchemaElement element = new XmlSchemaElement(); | 
					
						
							|  |  |  |             element.MinOccurs = repeats || valueTypeOptional ? 0 : 1; | 
					
						
							|  |  |  |             element.MaxOccurs = repeats ? decimal.MaxValue : 1; | 
					
						
							|  |  |  |             element.Name = accessor.Name; | 
					
						
							|  |  |  |             element.IsNillable = accessor.IsNullable || accessor.Mapping is NullableMapping; | 
					
						
							|  |  |  |             element.Form = XmlSchemaForm.Unqualified; | 
					
						
							|  |  |  |             element.SchemaTypeName = ExportTypeMapping(accessor.Mapping, accessor.Namespace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             group.Items.Add(element); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportRootMapping(StructMapping mapping) { | 
					
						
							|  |  |  |             if (!exportedRoot) { | 
					
						
							|  |  |  |                 exportedRoot = true; | 
					
						
							|  |  |  |                 ExportDerivedMappings(mapping); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportStructMapping(StructMapping mapping, string ns) { | 
					
						
							|  |  |  |             if (mapping.TypeDesc.IsRoot) return ExportRootMapping(mapping); | 
					
						
							|  |  |  |             XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping]; | 
					
						
							|  |  |  |             if (type == null) { | 
					
						
							|  |  |  |                 if (!mapping.IncludeInSchema) throw new InvalidOperationException(Res.GetString(Res.XmlSoapCannotIncludeInSchema, mapping.TypeDesc.Name)); | 
					
						
							|  |  |  |                 CheckForDuplicateType(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |                 type = new XmlSchemaComplexType(); | 
					
						
							|  |  |  |                 type.Name = mapping.TypeName; | 
					
						
							|  |  |  |                 types.Add(mapping, type); | 
					
						
							|  |  |  |                 AddSchemaItem(type, mapping.Namespace, ns); | 
					
						
							|  |  |  |                 type.IsAbstract = mapping.TypeDesc.IsAbstract; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (mapping.BaseMapping != null && mapping.BaseMapping.IncludeInSchema) { | 
					
						
							|  |  |  |                     XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension(); | 
					
						
							|  |  |  |                     extension.BaseTypeName = ExportStructMapping(mapping.BaseMapping, mapping.Namespace); | 
					
						
							|  |  |  |                     XmlSchemaComplexContent model = new XmlSchemaComplexContent(); | 
					
						
							|  |  |  |                     model.Content = extension; | 
					
						
							|  |  |  |                     type.ContentModel = model; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 ExportTypeMembers(type, mapping.Members, mapping.Namespace); | 
					
						
							|  |  |  |                 ExportDerivedMappings(mapping); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 AddSchemaImport(mapping.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(type.Name, mapping.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportMembersMapping(MembersMapping mapping, string ns) { | 
					
						
							|  |  |  |             XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping]; | 
					
						
							|  |  |  |             if(type == null) { | 
					
						
							|  |  |  |                 CheckForDuplicateType(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |                 type = new XmlSchemaComplexType(); | 
					
						
							|  |  |  |                 type.Name = mapping.TypeName; | 
					
						
							|  |  |  |                 types.Add(mapping, type); | 
					
						
							|  |  |  |                 AddSchemaItem(type, mapping.Namespace, ns); | 
					
						
							|  |  |  |                 ExportTypeMembers(type, mapping.Members, mapping.Namespace); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 AddSchemaImport(mapping.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(type.Name, mapping.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void ExportTypeMembers(XmlSchemaComplexType type, MemberMapping[] members, string ns) { | 
					
						
							|  |  |  |             XmlSchemaGroupBase seq = new XmlSchemaSequence(); | 
					
						
							|  |  |  |             for (int i = 0; i < members.Length; i++) { | 
					
						
							|  |  |  |                 MemberMapping member = members[i]; | 
					
						
							|  |  |  |                 if (member.Elements.Length > 0) { | 
					
						
							|  |  |  |                     bool valueTypeOptional = member.CheckSpecified != SpecifiedAccessor.None || member.CheckShouldPersist || !member.TypeDesc.IsValueType;  | 
					
						
							|  |  |  |                     ExportElementAccessors(seq, member.Elements, false, valueTypeOptional, ns); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             if (seq.Items.Count > 0) { | 
					
						
							|  |  |  |                 if (type.ContentModel != null) { | 
					
						
							|  |  |  |                     if (type.ContentModel.Content is XmlSchemaComplexContentExtension) | 
					
						
							|  |  |  |                         ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Particle = seq; | 
					
						
							|  |  |  |                     else if (type.ContentModel.Content is XmlSchemaComplexContentRestriction) | 
					
						
							|  |  |  |                         ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Particle = seq; | 
					
						
							|  |  |  |                     else | 
					
						
							|  |  |  |                         throw new InvalidOperationException(Res.GetString(Res.XmlInvalidContent, type.ContentModel.Content.GetType().Name)); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     type.Particle = seq; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         void ExportDerivedMappings(StructMapping mapping) { | 
					
						
							|  |  |  |             for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) { | 
					
						
							|  |  |  |                 if (derived.IncludeInSchema) ExportStructMapping(derived, mapping.TypeDesc.IsRoot ? null : mapping.Namespace); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         XmlQualifiedName ExportEnumMapping(EnumMapping mapping, string ns) { | 
					
						
							|  |  |  |             XmlSchemaSimpleType dataType = (XmlSchemaSimpleType)types[mapping]; | 
					
						
							|  |  |  |             if (dataType == null) { | 
					
						
							|  |  |  |                 CheckForDuplicateType(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |                 dataType = new XmlSchemaSimpleType(); | 
					
						
							|  |  |  |                 dataType.Name = mapping.TypeName; | 
					
						
							|  |  |  |                 types.Add(mapping, dataType); | 
					
						
							|  |  |  |                 AddSchemaItem(dataType, mapping.Namespace, ns); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction(); | 
					
						
							|  |  |  |                 restriction.BaseTypeName = new XmlQualifiedName("string", XmlSchema.Namespace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for (int i = 0; i < mapping.Constants.Length; i++) { | 
					
						
							|  |  |  |                     ConstantMapping constant = mapping.Constants[i]; | 
					
						
							|  |  |  |                     XmlSchemaEnumerationFacet enumeration = new XmlSchemaEnumerationFacet(); | 
					
						
							|  |  |  |                     enumeration.Value = constant.XmlName; | 
					
						
							|  |  |  |                     restriction.Facets.Add(enumeration); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (!mapping.IsFlags) { | 
					
						
							|  |  |  |                     dataType.Content = restriction; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else { | 
					
						
							|  |  |  |                     XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList(); | 
					
						
							|  |  |  |                     XmlSchemaSimpleType enumType = new XmlSchemaSimpleType(); | 
					
						
							|  |  |  |                     enumType.Content =  restriction; | 
					
						
							|  |  |  |                     list.ItemType = enumType; | 
					
						
							|  |  |  |                     dataType.Content =  list; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 AddSchemaImport(mapping.Namespace, ns); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             return new XmlQualifiedName(mapping.TypeName, mapping.Namespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |