(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / System.Xml.Serialization / XmlSchemaExporter.cs
blobe2237a592a62bbb405fb842b6c2a1b650b0fd54b
1 //
2 // System.Xml.Serialization.XmlSchemaExporter
3 //
4 // Author:
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // Copyright (C) Tim Coleman, 2002
9 //
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:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
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.
32 using System.Xml;
33 using System.Xml.Schema;
34 using System.Collections;
36 namespace System.Xml.Serialization {
37 public class XmlSchemaExporter {
39 #region Fields
41 XmlSchemas schemas;
42 Hashtable exportedMaps = new Hashtable();
43 Hashtable exportedElements = new Hashtable();
44 bool encodedFormat = false;
45 XmlDocument xmlDoc;
47 #endregion
49 #region Constructors
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
64 #region Methods
66 [MonoTODO]
67 public string ExportAnyType (string ns)
69 throw new NotImplementedException ();
72 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping)
74 ExportMembersMapping (xmlMembersMapping, true);
77 #if NET_2_0
78 public
79 #else
80 internal
81 #endif
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;
97 if (encodedFormat)
99 stype.Name = xmlMembersMapping.ElementName;
100 schema.Items.Add (stype);
102 else
104 XmlSchemaElement selem = new XmlSchemaElement ();
105 selem.Name = xmlMembersMapping.ElementName;
106 selem.SchemaType = stype;
107 schema.Items.Add (selem);
110 else
112 ICollection members = cmap.ElementMembers;
113 if (members != null)
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 ();
127 ct.Name = "any";
128 ct.IsMixed = true;
129 XmlSchemaSequence seq = new XmlSchemaSequence ();
130 ct.Particle = seq;
131 seq.Items.Add (par);
132 mschema.Items.Add (ct);
133 continue;
138 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) member.ElementInfo [0];
139 XmlSchema schema;
141 if (encodedFormat)
143 schema = GetSchema (xmlMembersMapping.Namespace);
144 ImportNamespace (schema, XmlSerializer.EncodingNamespace);
146 else
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);
158 else
159 elem = (XmlSchemaElement) GetSchemaElement (schema, einfo, false);
161 // In encoded format, the schema elements are not needed
162 if (!encodedFormat)
163 schema.Items.Add (elem);
165 if (exe != null)
167 if (exe.SchemaTypeName.Equals (elem.SchemaTypeName))
168 schema.Items.Remove (elem);
169 else
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);
181 CompileSchemas ();
184 [MonoTODO]
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;
195 if (encodedFormat)
197 ExportClassSchema (xmlTypeMapping);
198 XmlSchema schema = GetSchema (xmlTypeMapping.XmlTypeNamespace);
199 ImportNamespace (schema, XmlSerializer.EncodingNamespace);
201 else
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);
214 CompileSchemas ();
217 void ExportClassSchema (XmlTypeMapping map)
219 if (IsMapExported (map)) return;
220 SetMapExported (map);
222 if (map.TypeData.Type == typeof(object))
224 foreach (XmlTypeMapping dmap in map.DerivedTypes)
225 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
226 return;
229 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
230 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
231 stype.Name = map.XmlType;
232 schema.Items.Add (stype);
234 ClassMap cmap = (ClassMap)map.ObjectMap;
236 if (cmap.HasSimpleContent)
238 XmlSchemaSimpleContent simple = new XmlSchemaSimpleContent ();
239 stype.ContentModel = simple;
240 XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension ();
241 simple.Content = ext;
242 XmlSchemaSequence particle;
243 XmlSchemaAnyAttribute anyAttribute;
244 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
245 ext.AnyAttribute = anyAttribute;
246 if (map.BaseMap == null)
247 ext.BaseTypeName = cmap.SimpleContentBaseType;
248 else {
249 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
250 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
251 ExportClassSchema (map.BaseMap);
254 else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
256 XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
257 XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
258 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
259 cstype.Content = ext;
260 stype.ContentModel = cstype;
262 XmlSchemaSequence particle;
263 XmlSchemaAnyAttribute anyAttribute;
264 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
265 ext.Particle = particle;
266 ext.AnyAttribute = anyAttribute;
267 stype.IsMixed = HasMixedContent (map);
268 cstype.IsMixed = BaseHasMixedContent (map);
270 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
271 ExportClassSchema (map.BaseMap);
273 else
275 XmlSchemaSequence particle;
276 XmlSchemaAnyAttribute anyAttribute;
277 ExportMembersMapSchema (schema, cmap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
278 stype.Particle = particle;
279 stype.AnyAttribute = anyAttribute;
280 stype.IsMixed = cmap.XmlTextCollector != null;
283 foreach (XmlTypeMapping dmap in map.DerivedTypes)
284 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
287 bool BaseHasMixedContent (XmlTypeMapping map)
289 ClassMap cmap = (ClassMap)map.ObjectMap;
290 return (cmap.XmlTextCollector != null && (map.BaseMap != null && DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
293 bool HasMixedContent (XmlTypeMapping map)
295 ClassMap cmap = (ClassMap)map.ObjectMap;
296 return (cmap.XmlTextCollector != null && (map.BaseMap == null || !DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
299 void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
301 particle = null;
302 XmlSchemaSequence seq = new XmlSchemaSequence ();
304 ICollection members = map.ElementMembers;
305 if (members != null && !map.HasSimpleContent)
307 foreach (XmlTypeMapMemberElement member in members)
309 if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
311 Type memType = member.GetType();
312 if (memType == typeof(XmlTypeMapMemberFlatList))
314 XmlSchemaParticle part = GetSchemaArrayElement (schema, member.ElementInfo);
315 if (part != null) seq.Items.Add (part);
317 else if (memType == typeof(XmlTypeMapMemberAnyElement))
319 seq.Items.Add (GetSchemaArrayElement (schema, member.ElementInfo));
321 else if (memType == typeof(XmlTypeMapMemberElement))
323 XmlSchemaParticle elem = GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], member.DefaultValue, true);
324 if (elem != null)
325 seq.Items.Add (elem);
327 else
329 seq.Items.Add (GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0], true));
334 if (seq.Items.Count > 0)
335 particle = seq;
337 // Write attributes
339 ICollection attributes = map.AttributeMembers;
340 if (attributes != null)
342 foreach (XmlTypeMapMemberAttribute attr in attributes) {
343 if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
344 outAttributes.Add (GetSchemaAttribute (schema, attr, true));
348 XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
349 if (anyAttrMember != null)
350 anyAttribute = new XmlSchemaAnyAttribute ();
351 else
352 anyAttribute = null;
355 XmlSchemaElement FindElement (XmlSchemaObjectCollection col, string name)
357 foreach (XmlSchemaObject ob in col)
359 XmlSchemaElement elem = ob as XmlSchemaElement;
360 if (elem != null && elem.Name == name) return elem;
362 return null;
365 XmlSchemaComplexType FindComplexType (XmlSchemaObjectCollection col, string name)
367 foreach (XmlSchemaObject ob in col)
369 XmlSchemaComplexType ctype = ob as XmlSchemaComplexType;
370 if (ctype != null && ctype.Name == name) return ctype;
372 return null;
375 XmlSchemaAttribute GetSchemaAttribute (XmlSchema currentSchema, XmlTypeMapMemberAttribute attinfo, bool isTypeMember)
377 XmlSchemaAttribute sat = new XmlSchemaAttribute ();
378 if (attinfo.DefaultValue != System.DBNull.Value) sat.DefaultValue = XmlCustomFormatter.ToXmlString (attinfo.TypeData, attinfo.DefaultValue);
380 ImportNamespace (currentSchema, attinfo.Namespace);
382 XmlSchema memberSchema;
383 if (attinfo.Namespace.Length == 0 && attinfo.Form != XmlSchemaForm.Qualified)
384 memberSchema = currentSchema;
385 else
386 memberSchema = GetSchema (attinfo.Namespace);
388 if (currentSchema == memberSchema || encodedFormat)
390 sat.Name = attinfo.AttributeName;
391 if (isTypeMember) sat.Form = attinfo.Form;
392 if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
394 ImportNamespace (currentSchema, attinfo.DataTypeNamespace);
395 ExportEnumSchema (attinfo.MappedType);
396 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
398 else if (attinfo.TypeData.SchemaType == SchemaTypes.Array && TypeTranslator.IsPrimitive (attinfo.TypeData.ListItemType))
400 sat.SchemaType = GetSchemaSimpleListType (attinfo.TypeData);
402 else
403 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
405 else
407 sat.RefName = new XmlQualifiedName (attinfo.AttributeName, attinfo.Namespace);
408 foreach (XmlSchemaObject ob in memberSchema.Items)
409 if (ob is XmlSchemaAttribute && ((XmlSchemaAttribute)ob).Name == attinfo.AttributeName)
410 return sat;
412 memberSchema.Items.Add (GetSchemaAttribute (memberSchema, attinfo, false));
414 return sat;
417 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
419 return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember);
422 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember)
424 if (einfo.IsTextElement) return null;
426 if (einfo.IsUnnamedAnyElement)
428 XmlSchemaAny any = new XmlSchemaAny ();
429 any.MinOccurs = 0;
430 any.MaxOccurs = 1;
431 return any;
434 XmlSchemaElement selem = new XmlSchemaElement ();
436 if (isTypeMember)
438 selem.MaxOccurs = 1;
439 selem.MinOccurs = einfo.IsNullable ? 1 : 0;
441 if ((einfo.TypeData.IsValueType && einfo.Member != null && !einfo.Member.IsOptionalValueType) || encodedFormat)
442 selem.MinOccurs = 1;
445 XmlSchema memberSchema = null;
447 if (!encodedFormat)
449 memberSchema = GetSchema (einfo.Namespace);
450 ImportNamespace (currentSchema, einfo.Namespace);
453 if (currentSchema == memberSchema || encodedFormat || !isTypeMember)
455 if (isTypeMember) selem.IsNillable = einfo.IsNullable;
456 selem.Name = einfo.ElementName;
457 XmlQualifiedName typeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
459 if (defaultValue != System.DBNull.Value)
460 selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
462 if (einfo.Form != XmlSchemaForm.Qualified)
463 selem.Form = einfo.Form;
465 switch (einfo.TypeData.SchemaType)
467 case SchemaTypes.XmlNode:
468 selem.SchemaType = GetSchemaXmlNodeType ();
469 break;
471 case SchemaTypes.XmlSerializable:
472 selem.SchemaType = GetSchemaXmlSerializableType ();
473 break;
475 case SchemaTypes.Enum:
476 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
477 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
478 ExportEnumSchema (einfo.MappedType);
479 break;
481 case SchemaTypes.Array:
482 XmlQualifiedName atypeName = ExportArraySchema (einfo.MappedType, currentSchema.TargetNamespace);
483 selem.SchemaTypeName = atypeName;
484 ImportNamespace (currentSchema, atypeName.Namespace);
485 break;
487 case SchemaTypes.Class:
488 if (einfo.MappedType.TypeData.Type != typeof(object)) {
489 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
490 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
492 else if (encodedFormat)
493 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
495 ExportClassSchema (einfo.MappedType);
496 break;
498 case SchemaTypes.Primitive:
499 selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);;
500 break;
503 else
505 selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
506 foreach (XmlSchemaObject ob in memberSchema.Items)
507 if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
508 return selem;
510 memberSchema.Items.Add (GetSchemaElement (memberSchema, einfo, defaultValue, false));
512 return selem;
515 void ImportNamespace (XmlSchema schema, string ns)
517 if (ns == "" || ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
519 foreach (XmlSchemaObject sob in schema.Includes)
520 if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
522 XmlSchemaImport imp = new XmlSchemaImport ();
523 imp.Namespace = ns;
524 schema.Includes.Add (imp);
527 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
529 if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
530 return true;
531 else if (map.BaseMap != null)
532 return DefinedInBaseMap (map.BaseMap, member);
533 else
534 return false;
537 XmlSchemaType GetSchemaXmlNodeType ()
539 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
540 stype.IsMixed = true;
541 XmlSchemaSequence seq = new XmlSchemaSequence ();
542 seq.Items.Add (new XmlSchemaAny ());
543 stype.Particle = seq;
544 return stype;
547 XmlSchemaType GetSchemaXmlSerializableType ()
549 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
550 XmlSchemaSequence seq = new XmlSchemaSequence ();
551 XmlSchemaElement selem = new XmlSchemaElement ();
552 selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
553 seq.Items.Add (selem);
554 seq.Items.Add (new XmlSchemaAny ());
555 stype.Particle = seq;
556 return stype;
559 XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
561 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
562 XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
563 TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
564 list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
565 stype.Content = list;
566 return stype;
569 XmlSchemaParticle GetSchemaArrayElement (XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
571 int numInfos = infos.Count;
572 if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
573 if (numInfos == 0) return null;
575 if (numInfos == 1)
577 XmlSchemaParticle selem = GetSchemaElement (currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
578 selem.MinOccursString = "0";
579 selem.MaxOccursString = "unbounded";
580 return selem;
582 else
584 XmlSchemaChoice schoice = new XmlSchemaChoice ();
585 schoice.MinOccursString = "0";
586 schoice.MaxOccursString = "unbounded";
587 foreach (XmlTypeMapElementInfo einfo in infos)
589 if (einfo.IsTextElement) continue;
590 schoice.Items.Add (GetSchemaElement (currentSchema, einfo, true));
592 return schoice;
596 void ExportEnumSchema (XmlTypeMapping map)
598 if (IsMapExported (map)) return;
599 SetMapExported (map);
601 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
602 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
603 stype.Name = map.ElementName;
604 schema.Items.Add (stype);
606 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
607 rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
608 EnumMap emap = (EnumMap) map.ObjectMap;
610 foreach (EnumMap.EnumMapMember emem in emap.Members)
612 XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
613 ef.Value = emem.XmlName;
614 rest.Facets.Add (ef);
616 stype.Content = rest;
619 XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
621 ListMap lmap = (ListMap) map.ObjectMap;
623 if (encodedFormat)
625 string name, ns, schemaNs;
626 lmap.GetArrayType (-1, out name, out ns);
627 if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
628 else schemaNs = ns;
630 if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
631 SetMapExported (map);
633 XmlSchema schema = GetSchema (schemaNs);
634 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
635 stype.Name = lmap.GetSchemaArrayName ();
636 schema.Items.Add (stype);
638 XmlSchemaComplexContent content = new XmlSchemaComplexContent();
639 content.IsMixed = false;
640 stype.ContentModel = content;
642 XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
643 content.Content = rest;
644 rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
645 XmlSchemaAttribute at = new XmlSchemaAttribute ();
646 rest.Attributes.Add (at);
647 at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
649 XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
650 arrayType.Value = ns + (ns != "" ? ":" : "") + name;
651 at.UnhandledAttributes = new XmlAttribute [] { arrayType };
652 ImportNamespace (schema, XmlSerializer.WsdlNamespace);
654 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
655 if (einfo.MappedType != null)
657 switch (einfo.TypeData.SchemaType)
659 case SchemaTypes.Enum:
660 ExportEnumSchema (einfo.MappedType);
661 break;
662 case SchemaTypes.Array:
663 ExportArraySchema (einfo.MappedType, schemaNs);
664 break;
665 case SchemaTypes.Class:
666 ExportClassSchema (einfo.MappedType);
667 break;
671 return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
673 else
675 if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
677 SetMapExported (map);
678 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
679 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
680 stype.Name = map.ElementName;
681 schema.Items.Add (stype);
683 XmlSchemaParticle spart = GetSchemaArrayElement (schema, lmap.ItemInfo);
684 if (spart is XmlSchemaChoice)
685 stype.Particle = spart;
686 else
688 XmlSchemaSequence seq = new XmlSchemaSequence ();
689 seq.Items.Add (spart);
690 stype.Particle = seq;
693 return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
697 XmlDocument Document
701 if (xmlDoc == null) xmlDoc = new XmlDocument ();
702 return xmlDoc;
706 bool IsMapExported (XmlTypeMapping map)
708 if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
709 return false;
712 void SetMapExported (XmlTypeMapping map)
714 exportedMaps [GetMapKey(map)] = map;
717 bool IsElementExported (XmlTypeMapping map)
719 if (exportedElements.ContainsKey (GetMapKey(map))) return true;
720 if (map.TypeData.Type == typeof(object)) return true;
721 return false;
724 void SetElementExported (XmlTypeMapping map)
726 exportedElements [GetMapKey(map)] = map;
729 string GetMapKey (XmlTypeMapping map)
731 // Don't use type name for array types, since we can have different
732 // classes that represent the same array type (for example
733 // StringCollection and string[]).
735 if (map.TypeData.IsListType)
736 return GetArrayKeyName (map.TypeData) + " " + map.XmlType + " " + map.XmlTypeNamespace;
737 else
738 return map.TypeData.FullTypeName + " " + map.XmlType + " " + map.XmlTypeNamespace;
741 string GetArrayKeyName (TypeData td)
743 TypeData etd = td.ListItemTypeData;
744 return "*arrayof*" + (etd.IsListType ? GetArrayKeyName (etd) : etd.FullTypeName);
747 void CompileSchemas ()
749 // foreach (XmlSchema sc in schemas)
750 // sc.Compile (null);
753 XmlSchema GetSchema (string ns)
755 XmlSchema schema = schemas [ns];
756 if (schema == null)
758 schema = new XmlSchema ();
759 schema.TargetNamespace = ns;
760 if (!encodedFormat)
761 schema.ElementFormDefault = XmlSchemaForm.Qualified;
762 schemas.Add (schema);
764 return schema;
767 #endregion // Methods