2 // System.Xml.Serialization.XmlSchemaExporter
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Xml.Schema;
34 using System.Collections;
36 namespace System.Xml.Serialization {
37 public class XmlSchemaExporter {
42 Hashtable exportedMaps = new Hashtable();
43 Hashtable exportedElements = new Hashtable();
44 bool encodedFormat = false;
51 public XmlSchemaExporter (XmlSchemas schemas)
53 this.schemas = schemas;
56 internal XmlSchemaExporter (XmlSchemas schemas, bool encodedFormat)
58 this.encodedFormat = encodedFormat;
59 this.schemas = schemas;
62 #endregion // Constructors
67 public string ExportAnyType (string ns)
69 throw new NotImplementedException ();
72 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
74 ExportMembersMapping (xmlMembersMapping, true);
82 void ExportMembersMapping (XmlMembersMapping xmlMembersMapping, bool exportEnclosingType)
84 ClassMap cmap = (ClassMap) xmlMembersMapping.ObjectMap;
86 if (xmlMembersMapping.HasWrapperElement && exportEnclosingType)
88 XmlSchema schema = GetSchema (xmlMembersMapping.Namespace);
89 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
91 XmlSchemaSequence particle;
92 XmlSchemaAnyAttribute anyAttribute;
93 ExportMembersMapSchema (schema, cmap, null, stype.Attributes, out particle, out anyAttribute);
94 stype.Particle = particle;
95 stype.AnyAttribute = anyAttribute;
99 stype.Name = xmlMembersMapping.ElementName;
100 schema.Items.Add (stype);
104 XmlSchemaElement selem = new XmlSchemaElement ();
105 selem.Name = xmlMembersMapping.ElementName;
106 selem.SchemaType = stype;
107 schema.Items.Add (selem);
112 ICollection members = cmap.ElementMembers;
115 foreach (XmlTypeMapMemberElement member in members)
117 if (member is XmlTypeMapMemberAnyElement && member.TypeData.IsListType)
119 XmlSchema mschema = GetSchema (xmlMembersMapping.Namespace);
120 XmlSchemaParticle par = GetSchemaArrayElement (mschema, member.ElementInfo);
121 if (par is XmlSchemaAny)
123 XmlSchemaComplexType ct = FindComplexType (mschema.Items, "any");
124 if (ct != null) continue;
126 ct = new XmlSchemaComplexType ();
129 XmlSchemaSequence seq = new XmlSchemaSequence ();
132 mschema.Items.Add (ct);
138 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo [0];
143 schema = GetSchema (xmlMembersMapping.Namespace);
144 ImportNamespace (schema, XmlSerializer.EncodingNamespace);
147 schema = GetSchema (einfo.Namespace);
150 XmlSchemaElement exe = FindElement (schema.Items, einfo.ElementName);
151 XmlSchemaElement elem;
153 Type memType = member.GetType();
154 if (member is XmlTypeMapMemberFlatList)
155 throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
156 else if (memType == typeof(XmlTypeMapMemberElement))
157 elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, member.DefaultValue, false);
159 elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, false);
161 // In encoded format, the schema elements are not needed
163 schema.Items.Add (elem);
167 if (exe.SchemaTypeName.Equals (elem.SchemaTypeName))
168 schema.Items.Remove (elem);
171 string s = "The XML element named '" + einfo.ElementName + "' ";
172 s += "from namespace '" + schema.TargetNamespace + "' references distinct types " + elem.SchemaTypeName.Name + " and " + exe.SchemaTypeName.Name + ". ";
173 s += "Use XML attributes to specify another XML name or namespace for the element or types.";
174 throw new InvalidOperationException (s);
185 public XmlQualifiedName ExportTypeMapping (XmlMembersMapping xmlMembersMapping)
187 throw new NotImplementedException ();
190 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
192 if (!xmlTypeMapping.IncludeInSchema) return;
193 if (IsElementExported (xmlTypeMapping)) return;
197 ExportClassSchema (xmlTypeMapping);
198 XmlSchema schema = GetSchema (xmlTypeMapping.XmlTypeNamespace);
199 ImportNamespace (schema, XmlSerializer.EncodingNamespace);
203 XmlSchema schema = GetSchema (xmlTypeMapping.Namespace);
204 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (null, xmlTypeMapping.TypeData);
205 einfo.Namespace = xmlTypeMapping.Namespace;
206 einfo.ElementName = xmlTypeMapping.ElementName;
207 if (xmlTypeMapping.TypeData.IsComplexType)
208 einfo.MappedType = xmlTypeMapping;
209 einfo.IsNullable = false;
210 schema.Items.Add (GetSchemaElement (schema, einfo, false));
211 SetElementExported (xmlTypeMapping);
217 void ExportXmlSerializableSchema (XmlSchema currentSchema, XmlSerializableMapping map)
219 if (IsMapExported (map)) return;
220 SetMapExported (map);
222 if (map.Schema == null) return;
224 string targetNs = map.Schema.TargetNamespace;
225 XmlSchema existingSchema = schemas [targetNs];
226 if (existingSchema == null)
228 schemas.Add (map.Schema);
229 ImportNamespace (currentSchema, targetNs);
231 else if (existingSchema != map.Schema)
233 throw new InvalidOperationException("The namespace '" + targetNs +"' defined by the class '" + map.TypeFullName + "' is a duplicate.");
237 void ExportClassSchema (XmlTypeMapping map)
239 if (IsMapExported (map)) return;
240 SetMapExported (map);
242 if (map.TypeData.Type == typeof(object))
244 foreach (XmlTypeMapping dmap in map.DerivedTypes)
245 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
249 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
250 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
251 stype.Name = map.XmlType;
252 schema.Items.Add (stype);
254 ClassMap cmap = (ClassMap)map.ObjectMap;
256 if (cmap.HasSimpleContent)
258 XmlSchemaSimpleContent simple = new XmlSchemaSimpleContent ();
259 stype.ContentModel = simple;
260 XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension ();
261 simple.Content = ext;
262 XmlSchemaSequence particle;
263 XmlSchemaAnyAttribute anyAttribute;
264 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
265 ext.AnyAttribute = anyAttribute;
266 if (map.BaseMap == null)
267 ext.BaseTypeName = cmap.SimpleContentBaseType;
269 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
270 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
271 ExportClassSchema (map.BaseMap);
274 else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
276 XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
277 XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
278 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
279 cstype.Content = ext;
280 stype.ContentModel = cstype;
282 XmlSchemaSequence particle;
283 XmlSchemaAnyAttribute anyAttribute;
284 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
285 ext.Particle = particle;
286 ext.AnyAttribute = anyAttribute;
287 stype.IsMixed = HasMixedContent (map);
288 cstype.IsMixed = BaseHasMixedContent (map);
290 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
291 ExportClassSchema (map.BaseMap);
295 XmlSchemaSequence particle;
296 XmlSchemaAnyAttribute anyAttribute;
297 ExportMembersMapSchema (schema, cmap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
298 stype.Particle = particle;
299 stype.AnyAttribute = anyAttribute;
300 stype.IsMixed = cmap.XmlTextCollector != null;
303 foreach (XmlTypeMapping dmap in map.DerivedTypes)
304 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
307 bool BaseHasMixedContent (XmlTypeMapping map)
309 ClassMap cmap = (ClassMap)map.ObjectMap;
310 return (cmap.XmlTextCollector != null && (map.BaseMap != null && DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
313 bool HasMixedContent (XmlTypeMapping map)
315 ClassMap cmap = (ClassMap)map.ObjectMap;
316 return (cmap.XmlTextCollector != null && (map.BaseMap == null || !DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
319 void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
322 XmlSchemaSequence seq = new XmlSchemaSequence ();
324 ICollection members = map.ElementMembers;
325 if (members != null && !map.HasSimpleContent)
327 foreach (XmlTypeMapMemberElement member in members)
329 if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
331 Type memType = member.GetType();
332 if (memType == typeof(XmlTypeMapMemberFlatList))
334 XmlSchemaParticle part = GetSchemaArrayElement (schema, member.ElementInfo);
335 if (part != null) seq.Items.Add (part);
337 else if (memType == typeof(XmlTypeMapMemberAnyElement))
339 seq.Items.Add (GetSchemaArrayElement (schema, member.ElementInfo));
341 else if (memType == typeof(XmlTypeMapMemberElement))
343 XmlSchemaParticle elem = GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, true);
345 seq.Items.Add (elem);
349 seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true));
354 if (seq.Items.Count > 0)
359 ICollection attributes = map.AttributeMembers;
360 if (attributes != null)
362 foreach (XmlTypeMapMemberAttribute attr in attributes) {
363 if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
364 outAttributes.Add (GetSchemaAttribute (schema, attr, true));
368 XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
369 if (anyAttrMember != null)
370 anyAttribute = new XmlSchemaAnyAttribute ();
375 XmlSchemaElement FindElement (XmlSchemaObjectCollection col, string name)
377 foreach (XmlSchemaObject ob in col)
379 XmlSchemaElement elem = ob as XmlSchemaElement;
380 if (elem != null && elem.Name == name) return elem;
385 XmlSchemaComplexType FindComplexType (XmlSchemaObjectCollection col, string name)
387 foreach (XmlSchemaObject ob in col)
389 XmlSchemaComplexType ctype = ob as XmlSchemaComplexType;
390 if (ctype != null && ctype.Name == name) return ctype;
395 XmlSchemaAttribute GetSchemaAttribute (XmlSchema currentSchema, XmlTypeMapMemberAttribute attinfo, bool isTypeMember)
397 XmlSchemaAttribute sat = new XmlSchemaAttribute ();
398 if (attinfo.DefaultValue != System.DBNull.Value) sat.DefaultValue = XmlCustomFormatter.ToXmlString (attinfo.TypeData, attinfo.DefaultValue);
400 ImportNamespace (currentSchema, attinfo.Namespace);
402 XmlSchema memberSchema;
403 if (attinfo.Namespace.Length == 0 && attinfo.Form != XmlSchemaForm.Qualified)
404 memberSchema = currentSchema;
406 memberSchema = GetSchema (attinfo.Namespace);
408 if (currentSchema == memberSchema || encodedFormat)
410 sat.Name = attinfo.AttributeName;
411 if (isTypeMember) sat.Form = attinfo.Form;
412 if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
414 ImportNamespace (currentSchema, attinfo.DataTypeNamespace);
415 ExportEnumSchema (attinfo.MappedType);
416 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
418 else if (attinfo.TypeData.SchemaType == SchemaTypes.Array && TypeTranslator.IsPrimitive (attinfo.TypeData.ListItemType))
420 sat.SchemaType = GetSchemaSimpleListType (attinfo.TypeData);
423 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
427 sat.RefName = new XmlQualifiedName (attinfo.AttributeName, attinfo.Namespace);
428 foreach (XmlSchemaObject ob in memberSchema.Items)
429 if (ob is XmlSchemaAttribute && ((XmlSchemaAttribute)ob).Name == attinfo.AttributeName)
432 memberSchema.Items.Add (GetSchemaAttribute (memberSchema, attinfo, false));
437 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
439 return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember);
442 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember)
444 if (einfo.IsTextElement) return null;
446 if (einfo.IsUnnamedAnyElement)
448 XmlSchemaAny any = new XmlSchemaAny ();
454 XmlSchemaElement selem = new XmlSchemaElement ();
459 selem.MinOccurs = einfo.IsNullable ? 1 : 0;
461 if ((einfo.TypeData.IsValueType && einfo.Member != null && !einfo.Member.IsOptionalValueType) || encodedFormat)
465 XmlSchema memberSchema = null;
469 memberSchema = GetSchema (einfo.Namespace);
470 ImportNamespace (currentSchema, einfo.Namespace);
473 if (currentSchema == memberSchema || encodedFormat || !isTypeMember)
475 if (isTypeMember) selem.IsNillable = einfo.IsNullable;
476 selem.Name = einfo.ElementName;
478 if (defaultValue != System.DBNull.Value)
479 selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
481 if (einfo.Form != XmlSchemaForm.Qualified)
482 selem.Form = einfo.Form;
484 switch (einfo.TypeData.SchemaType)
486 case SchemaTypes.XmlNode:
487 selem.SchemaType = GetSchemaXmlNodeType ();
490 case SchemaTypes.XmlSerializable:
491 selem.SchemaType = GetSchemaXmlSerializableType (einfo.MappedType as XmlSerializableMapping);
492 ExportXmlSerializableSchema (currentSchema, einfo.MappedType as XmlSerializableMapping);
495 case SchemaTypes.Enum:
496 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
497 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
498 ExportEnumSchema (einfo.MappedType);
501 case SchemaTypes.Array:
502 XmlQualifiedName atypeName = ExportArraySchema (einfo.MappedType, currentSchema.TargetNamespace);
503 selem.SchemaTypeName = atypeName;
504 ImportNamespace (currentSchema, atypeName.Namespace);
507 case SchemaTypes.Class:
508 if (einfo.MappedType.TypeData.Type != typeof(object)) {
509 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
510 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
512 else if (encodedFormat)
513 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
515 ExportClassSchema (einfo.MappedType);
518 case SchemaTypes.Primitive:
519 selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);;
525 selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
526 foreach (XmlSchemaObject ob in memberSchema.Items)
527 if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
530 memberSchema.Items.Add (GetSchemaElement (memberSchema, einfo, defaultValue, false));
535 void ImportNamespace (XmlSchema schema, string ns)
537 if (ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
539 foreach (XmlSchemaObject sob in schema.Includes)
540 if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
542 XmlSchemaImport imp = new XmlSchemaImport ();
544 schema.Includes.Add (imp);
547 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
549 if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
551 else if (map.BaseMap != null)
552 return DefinedInBaseMap (map.BaseMap, member);
557 XmlSchemaType GetSchemaXmlNodeType ()
559 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
560 stype.IsMixed = true;
561 XmlSchemaSequence seq = new XmlSchemaSequence ();
562 seq.Items.Add (new XmlSchemaAny ());
563 stype.Particle = seq;
567 XmlSchemaType GetSchemaXmlSerializableType (XmlSerializableMapping map)
569 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
570 XmlSchemaSequence seq = new XmlSchemaSequence ();
571 if (map.Schema == null) {
572 XmlSchemaElement selem = new XmlSchemaElement ();
573 selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
574 seq.Items.Add (selem);
575 seq.Items.Add (new XmlSchemaAny ());
577 XmlSchemaAny any = new XmlSchemaAny ();
578 any.Namespace = map.Schema.TargetNamespace;
581 stype.Particle = seq;
585 XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
587 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
588 XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
589 TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
590 list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
591 stype.Content = list;
595 XmlSchemaParticle GetSchemaArrayElement (XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
597 int numInfos = infos.Count;
598 if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
599 if (numInfos == 0) return null;
603 XmlSchemaParticle selem = GetSchemaElement (currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
604 selem.MinOccursString = "0";
605 selem.MaxOccursString = "unbounded";
610 XmlSchemaChoice schoice = new XmlSchemaChoice ();
611 schoice.MinOccursString = "0";
612 schoice.MaxOccursString = "unbounded";
613 foreach (XmlTypeMapElementInfo einfo in infos)
615 if (einfo.IsTextElement) continue;
616 schoice.Items.Add (GetSchemaElement (currentSchema, einfo, true));
622 void ExportEnumSchema (XmlTypeMapping map)
624 if (IsMapExported (map)) return;
625 SetMapExported (map);
627 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
628 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
629 stype.Name = map.ElementName;
630 schema.Items.Add (stype);
632 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
633 rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
634 EnumMap emap = (EnumMap) map.ObjectMap;
636 foreach (EnumMap.EnumMapMember emem in emap.Members)
638 XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
639 ef.Value = emem.XmlName;
640 rest.Facets.Add (ef);
642 stype.Content = rest;
645 XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
647 ListMap lmap = (ListMap) map.ObjectMap;
651 string name, ns, schemaNs;
652 lmap.GetArrayType (-1, out name, out ns);
653 if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
656 if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
657 SetMapExported (map);
659 XmlSchema schema = GetSchema (schemaNs);
660 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
661 stype.Name = lmap.GetSchemaArrayName ();
662 schema.Items.Add (stype);
664 XmlSchemaComplexContent content = new XmlSchemaComplexContent();
665 content.IsMixed = false;
666 stype.ContentModel = content;
668 XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
669 content.Content = rest;
670 rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
671 XmlSchemaAttribute at = new XmlSchemaAttribute ();
672 rest.Attributes.Add (at);
673 at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
675 XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
676 arrayType.Value = ns + (ns != "" ? ":" : "") + name;
677 at.UnhandledAttributes = new XmlAttribute [] { arrayType };
678 ImportNamespace (schema, XmlSerializer.WsdlNamespace);
680 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
681 if (einfo.MappedType != null)
683 switch (einfo.TypeData.SchemaType)
685 case SchemaTypes.Enum:
686 ExportEnumSchema (einfo.MappedType);
688 case SchemaTypes.Array:
689 ExportArraySchema (einfo.MappedType, schemaNs);
691 case SchemaTypes.Class:
692 ExportClassSchema (einfo.MappedType);
697 return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
701 if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
703 SetMapExported (map);
704 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
705 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
706 stype.Name = map.ElementName;
707 schema.Items.Add (stype);
709 XmlSchemaParticle spart = GetSchemaArrayElement (schema, lmap.ItemInfo);
710 if (spart is XmlSchemaChoice)
711 stype.Particle = spart;
714 XmlSchemaSequence seq = new XmlSchemaSequence ();
715 seq.Items.Add (spart);
716 stype.Particle = seq;
719 return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
727 if (xmlDoc == null) xmlDoc = new XmlDocument ();
732 bool IsMapExported (XmlTypeMapping map)
734 if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
738 void SetMapExported (XmlTypeMapping map)
740 exportedMaps [GetMapKey(map)] = map;
743 bool IsElementExported (XmlTypeMapping map)
745 if (exportedElements.ContainsKey (GetMapKey(map))) return true;
746 if (map.TypeData.Type == typeof(object)) return true;
750 void SetElementExported (XmlTypeMapping map)
752 exportedElements [GetMapKey(map)] = map;
755 string GetMapKey (XmlTypeMapping map)
757 // Don't use type name for array types, since we can have different
758 // classes that represent the same array type (for example
759 // StringCollection and string[]).
761 if (map.TypeData.IsListType)
762 return GetArrayKeyName (map.TypeData) + " " + map.XmlType + " " + map.XmlTypeNamespace;
764 return map.TypeData.FullTypeName + " " + map.XmlType + " " + map.XmlTypeNamespace;
767 string GetArrayKeyName (TypeData td)
769 TypeData etd = td.ListItemTypeData;
770 return "*arrayof*" + (etd.IsListType ? GetArrayKeyName (etd) : etd.FullTypeName);
773 void CompileSchemas ()
775 // foreach (XmlSchema sc in schemas)
776 // sc.Compile (null);
779 XmlSchema GetSchema (string ns)
781 XmlSchema schema = schemas [ns];
784 schema = new XmlSchema ();
785 schema.TargetNamespace = ns;
787 schema.ElementFormDefault = XmlSchemaForm.Qualified;
788 schemas.Add (schema);
793 #endregion // Methods