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);;
520 if (!einfo.TypeData.IsXsdType)
521 ExportDerivedSchema (einfo.MappedType);
527 selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
528 foreach (XmlSchemaObject ob in memberSchema.Items)
529 if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
532 memberSchema.Items.Add (GetSchemaElement (memberSchema, einfo, defaultValue, false));
537 void ImportNamespace (XmlSchema schema, string ns)
539 if (ns == null || ns.Length == 0 ||
540 ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
542 foreach (XmlSchemaObject sob in schema.Includes)
543 if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
545 XmlSchemaImport imp = new XmlSchemaImport ();
547 schema.Includes.Add (imp);
550 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
552 if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
554 else if (map.BaseMap != null)
555 return DefinedInBaseMap (map.BaseMap, member);
560 XmlSchemaType GetSchemaXmlNodeType ()
562 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
563 stype.IsMixed = true;
564 XmlSchemaSequence seq = new XmlSchemaSequence ();
565 seq.Items.Add (new XmlSchemaAny ());
566 stype.Particle = seq;
570 XmlSchemaType GetSchemaXmlSerializableType (XmlSerializableMapping map)
572 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
573 XmlSchemaSequence seq = new XmlSchemaSequence ();
574 if (map.Schema == null) {
575 XmlSchemaElement selem = new XmlSchemaElement ();
576 selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
577 seq.Items.Add (selem);
578 seq.Items.Add (new XmlSchemaAny ());
580 XmlSchemaAny any = new XmlSchemaAny ();
581 any.Namespace = map.Schema.TargetNamespace;
584 stype.Particle = seq;
588 XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
590 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
591 XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
592 TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
593 list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
594 stype.Content = list;
598 XmlSchemaParticle GetSchemaArrayElement (XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
600 int numInfos = infos.Count;
601 if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
602 if (numInfos == 0) return null;
606 XmlSchemaParticle selem = GetSchemaElement (currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
607 selem.MinOccursString = "0";
608 selem.MaxOccursString = "unbounded";
613 XmlSchemaChoice schoice = new XmlSchemaChoice ();
614 schoice.MinOccursString = "0";
615 schoice.MaxOccursString = "unbounded";
616 foreach (XmlTypeMapElementInfo einfo in infos)
618 if (einfo.IsTextElement) continue;
619 schoice.Items.Add (GetSchemaElement (currentSchema, einfo, true));
625 void ExportDerivedSchema(XmlTypeMapping map) {
626 if (IsMapExported (map)) return;
627 SetMapExported (map);
629 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
630 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
631 stype.Name = map.ElementName;
632 schema.Items.Add (stype);
634 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
635 rest.BaseTypeName = new XmlQualifiedName (map.TypeData.MappedType.XmlType, XmlSchema.Namespace);
636 XmlSchemaPatternFacet facet = map.TypeData.XmlSchemaPatternFacet;
638 rest.Facets.Add(facet);
639 stype.Content = rest;
642 void ExportEnumSchema (XmlTypeMapping map)
644 if (IsMapExported (map)) return;
645 SetMapExported (map);
647 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
648 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
649 stype.Name = map.ElementName;
650 schema.Items.Add (stype);
652 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
653 rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
654 EnumMap emap = (EnumMap) map.ObjectMap;
656 foreach (EnumMap.EnumMapMember emem in emap.Members)
658 XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
659 ef.Value = emem.XmlName;
660 rest.Facets.Add (ef);
662 stype.Content = rest;
665 XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
667 ListMap lmap = (ListMap) map.ObjectMap;
671 string name, ns, schemaNs;
672 lmap.GetArrayType (-1, out name, out ns);
673 if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
676 if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
677 SetMapExported (map);
679 XmlSchema schema = GetSchema (schemaNs);
680 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
681 stype.Name = lmap.GetSchemaArrayName ();
682 schema.Items.Add (stype);
684 XmlSchemaComplexContent content = new XmlSchemaComplexContent();
685 content.IsMixed = false;
686 stype.ContentModel = content;
688 XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
689 content.Content = rest;
690 rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
691 XmlSchemaAttribute at = new XmlSchemaAttribute ();
692 rest.Attributes.Add (at);
693 at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
695 XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
696 arrayType.Value = ns + (ns != "" ? ":" : "") + name;
697 at.UnhandledAttributes = new XmlAttribute [] { arrayType };
698 ImportNamespace (schema, XmlSerializer.WsdlNamespace);
700 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
701 if (einfo.MappedType != null)
703 switch (einfo.TypeData.SchemaType)
705 case SchemaTypes.Enum:
706 ExportEnumSchema (einfo.MappedType);
708 case SchemaTypes.Array:
709 ExportArraySchema (einfo.MappedType, schemaNs);
711 case SchemaTypes.Class:
712 ExportClassSchema (einfo.MappedType);
717 return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
721 if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
723 SetMapExported (map);
724 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
725 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
726 stype.Name = map.ElementName;
727 schema.Items.Add (stype);
729 XmlSchemaParticle spart = GetSchemaArrayElement (schema, lmap.ItemInfo);
730 if (spart is XmlSchemaChoice)
731 stype.Particle = spart;
734 XmlSchemaSequence seq = new XmlSchemaSequence ();
735 seq.Items.Add (spart);
736 stype.Particle = seq;
739 return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
747 if (xmlDoc == null) xmlDoc = new XmlDocument ();
752 bool IsMapExported (XmlTypeMapping map)
754 if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
758 void SetMapExported (XmlTypeMapping map)
760 exportedMaps [GetMapKey(map)] = map;
763 bool IsElementExported (XmlTypeMapping map)
765 if (exportedElements.ContainsKey (GetMapKey(map))) return true;
766 if (map.TypeData.Type == typeof(object)) return true;
770 void SetElementExported (XmlTypeMapping map)
772 exportedElements [GetMapKey(map)] = map;
775 string GetMapKey (XmlTypeMapping map)
777 // Don't use type name for array types, since we can have different
778 // classes that represent the same array type (for example
779 // StringCollection and string[]).
781 if (map.TypeData.IsListType)
782 return GetArrayKeyName (map.TypeData) + " " + map.XmlType + " " + map.XmlTypeNamespace;
784 return map.TypeData.FullTypeName + " " + map.XmlType + " " + map.XmlTypeNamespace;
787 string GetArrayKeyName (TypeData td)
789 TypeData etd = td.ListItemTypeData;
790 return "*arrayof*" + (etd.IsListType ? GetArrayKeyName (etd) : etd.FullTypeName);
793 void CompileSchemas ()
795 // foreach (XmlSchema sc in schemas)
796 // sc.Compile (null);
799 XmlSchema GetSchema (string ns)
801 XmlSchema schema = schemas [ns];
804 schema = new XmlSchema ();
805 schema.TargetNamespace = ns;
807 schema.ElementFormDefault = XmlSchemaForm.Qualified;
808 schemas.Add (schema);
813 #endregion // Methods