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 XmlSchemaObjectContainer container = null;
154 // In encoded format, the schema elements are not needed
156 container = new XmlSchemaObjectContainer (schema);
158 Type memType = member.GetType();
159 if (member is XmlTypeMapMemberFlatList)
160 throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
161 else if (memType == typeof(XmlTypeMapMemberElement))
162 elem = (XmlSchemaElement) GetSchemaElement (schema,
163 einfo, member.DefaultValue, false, container);
165 elem = (XmlSchemaElement) GetSchemaElement (schema,
166 einfo, false, container);
170 if (exe.SchemaTypeName.Equals (elem.SchemaTypeName))
171 schema.Items.Remove (elem);
174 string s = "The XML element named '" + einfo.ElementName + "' ";
175 s += "from namespace '" + schema.TargetNamespace + "' references distinct types " + elem.SchemaTypeName.Name + " and " + exe.SchemaTypeName.Name + ". ";
176 s += "Use XML attributes to specify another XML name or namespace for the element or types.";
177 throw new InvalidOperationException (s);
188 public XmlQualifiedName ExportTypeMapping (XmlMembersMapping xmlMembersMapping)
190 throw new NotImplementedException ();
193 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping)
195 if (!xmlTypeMapping.IncludeInSchema) return;
196 if (IsElementExported (xmlTypeMapping)) return;
200 ExportClassSchema (xmlTypeMapping);
201 XmlSchema schema = GetSchema (xmlTypeMapping.XmlTypeNamespace);
202 ImportNamespace (schema, XmlSerializer.EncodingNamespace);
206 XmlSchema schema = GetSchema (xmlTypeMapping.Namespace);
207 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (null, xmlTypeMapping.TypeData);
208 einfo.Namespace = xmlTypeMapping.Namespace;
209 einfo.ElementName = xmlTypeMapping.ElementName;
210 if (xmlTypeMapping.TypeData.IsComplexType)
211 einfo.MappedType = xmlTypeMapping;
212 einfo.IsNullable = false;
213 GetSchemaElement (schema, einfo, false, new XmlSchemaObjectContainer (schema));
214 SetElementExported (xmlTypeMapping);
220 void ExportXmlSerializableSchema (XmlSchema currentSchema, XmlSerializableMapping map)
222 if (IsMapExported (map)) return;
223 SetMapExported (map);
225 if (map.Schema == null) return;
227 string targetNs = map.Schema.TargetNamespace;
228 XmlSchema existingSchema = schemas [targetNs];
229 if (existingSchema == null)
231 schemas.Add (map.Schema);
232 ImportNamespace (currentSchema, targetNs);
234 else if (existingSchema != map.Schema)
236 throw new InvalidOperationException("The namespace '" + targetNs +"' defined by the class '" + map.TypeFullName + "' is a duplicate.");
240 void ExportClassSchema (XmlTypeMapping map)
242 if (IsMapExported (map)) return;
243 SetMapExported (map);
245 if (map.TypeData.Type == typeof(object))
247 foreach (XmlTypeMapping dmap in map.DerivedTypes)
248 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
252 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
253 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
254 stype.Name = map.XmlType;
255 schema.Items.Add (stype);
257 ClassMap cmap = (ClassMap)map.ObjectMap;
259 if (cmap.HasSimpleContent)
261 XmlSchemaSimpleContent simple = new XmlSchemaSimpleContent ();
262 stype.ContentModel = simple;
263 XmlSchemaSimpleContentExtension ext = new XmlSchemaSimpleContentExtension ();
264 simple.Content = ext;
265 XmlSchemaSequence particle;
266 XmlSchemaAnyAttribute anyAttribute;
267 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
268 ext.AnyAttribute = anyAttribute;
269 if (map.BaseMap == null)
270 ext.BaseTypeName = cmap.SimpleContentBaseType;
272 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
273 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
274 ExportClassSchema (map.BaseMap);
277 else if (map.BaseMap != null && map.BaseMap.IncludeInSchema)
279 XmlSchemaComplexContent cstype = new XmlSchemaComplexContent ();
280 XmlSchemaComplexContentExtension ext = new XmlSchemaComplexContentExtension ();
281 ext.BaseTypeName = new XmlQualifiedName (map.BaseMap.XmlType, map.BaseMap.XmlTypeNamespace);
282 cstype.Content = ext;
283 stype.ContentModel = cstype;
285 XmlSchemaSequence particle;
286 XmlSchemaAnyAttribute anyAttribute;
287 ExportMembersMapSchema (schema, cmap, map.BaseMap, ext.Attributes, out particle, out anyAttribute);
288 ext.Particle = particle;
289 ext.AnyAttribute = anyAttribute;
290 stype.IsMixed = HasMixedContent (map);
291 cstype.IsMixed = BaseHasMixedContent (map);
293 ImportNamespace (schema, map.BaseMap.XmlTypeNamespace);
294 ExportClassSchema (map.BaseMap);
298 XmlSchemaSequence particle;
299 XmlSchemaAnyAttribute anyAttribute;
300 ExportMembersMapSchema (schema, cmap, map.BaseMap, stype.Attributes, out particle, out anyAttribute);
301 stype.Particle = particle;
302 stype.AnyAttribute = anyAttribute;
303 stype.IsMixed = cmap.XmlTextCollector != null;
306 foreach (XmlTypeMapping dmap in map.DerivedTypes)
307 if (dmap.TypeData.SchemaType == SchemaTypes.Class) ExportClassSchema (dmap);
310 bool BaseHasMixedContent (XmlTypeMapping map)
312 ClassMap cmap = (ClassMap)map.ObjectMap;
313 return (cmap.XmlTextCollector != null && (map.BaseMap != null && DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
316 bool HasMixedContent (XmlTypeMapping map)
318 ClassMap cmap = (ClassMap)map.ObjectMap;
319 return (cmap.XmlTextCollector != null && (map.BaseMap == null || !DefinedInBaseMap (map.BaseMap, cmap.XmlTextCollector)));
322 void ExportMembersMapSchema (XmlSchema schema, ClassMap map, XmlTypeMapping baseMap, XmlSchemaObjectCollection outAttributes, out XmlSchemaSequence particle, out XmlSchemaAnyAttribute anyAttribute)
325 XmlSchemaSequence seq = new XmlSchemaSequence ();
327 ICollection members = map.ElementMembers;
328 if (members != null && !map.HasSimpleContent)
330 foreach (XmlTypeMapMemberElement member in members)
332 if (baseMap != null && DefinedInBaseMap (baseMap, member)) continue;
334 Type memType = member.GetType();
335 if (memType == typeof(XmlTypeMapMemberFlatList))
337 XmlSchemaParticle part = GetSchemaArrayElement (schema, member.ElementInfo);
338 if (part != null) seq.Items.Add (part);
340 else if (memType == typeof(XmlTypeMapMemberAnyElement))
342 seq.Items.Add (GetSchemaArrayElement (schema, member.ElementInfo));
344 else if (memType == typeof(XmlTypeMapMemberElement))
346 GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo [0],
347 member.DefaultValue, true, new XmlSchemaObjectContainer (seq));
351 GetSchemaElement (schema, (XmlTypeMapElementInfo) member.ElementInfo[0],
352 true, new XmlSchemaObjectContainer (seq));
357 if (seq.Items.Count > 0)
362 ICollection attributes = map.AttributeMembers;
363 if (attributes != null)
365 foreach (XmlTypeMapMemberAttribute attr in attributes) {
366 if (baseMap != null && DefinedInBaseMap (baseMap, attr)) continue;
367 outAttributes.Add (GetSchemaAttribute (schema, attr, true));
371 XmlTypeMapMember anyAttrMember = map.DefaultAnyAttributeMember;
372 if (anyAttrMember != null)
373 anyAttribute = new XmlSchemaAnyAttribute ();
378 XmlSchemaElement FindElement (XmlSchemaObjectCollection col, string name)
380 foreach (XmlSchemaObject ob in col)
382 XmlSchemaElement elem = ob as XmlSchemaElement;
383 if (elem != null && elem.Name == name) return elem;
388 XmlSchemaComplexType FindComplexType (XmlSchemaObjectCollection col, string name)
390 foreach (XmlSchemaObject ob in col)
392 XmlSchemaComplexType ctype = ob as XmlSchemaComplexType;
393 if (ctype != null && ctype.Name == name) return ctype;
398 XmlSchemaAttribute GetSchemaAttribute (XmlSchema currentSchema, XmlTypeMapMemberAttribute attinfo, bool isTypeMember)
400 XmlSchemaAttribute sat = new XmlSchemaAttribute ();
401 if (attinfo.DefaultValue != System.DBNull.Value) sat.DefaultValue = XmlCustomFormatter.ToXmlString (attinfo.TypeData, attinfo.DefaultValue);
403 ImportNamespace (currentSchema, attinfo.Namespace);
405 XmlSchema memberSchema;
406 if (attinfo.Namespace.Length == 0 && attinfo.Form != XmlSchemaForm.Qualified)
407 memberSchema = currentSchema;
409 memberSchema = GetSchema (attinfo.Namespace);
411 if (currentSchema == memberSchema || encodedFormat)
413 sat.Name = attinfo.AttributeName;
414 if (isTypeMember) sat.Form = attinfo.Form;
415 if (attinfo.TypeData.SchemaType == SchemaTypes.Enum)
417 ImportNamespace (currentSchema, attinfo.DataTypeNamespace);
418 ExportEnumSchema (attinfo.MappedType);
419 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
421 else if (attinfo.TypeData.SchemaType == SchemaTypes.Array && TypeTranslator.IsPrimitive (attinfo.TypeData.ListItemType))
423 sat.SchemaType = GetSchemaSimpleListType (attinfo.TypeData);
426 sat.SchemaTypeName = new XmlQualifiedName (attinfo.TypeData.XmlType, attinfo.DataTypeNamespace);;
430 sat.RefName = new XmlQualifiedName (attinfo.AttributeName, attinfo.Namespace);
431 foreach (XmlSchemaObject ob in memberSchema.Items)
432 if (ob is XmlSchemaAttribute && ((XmlSchemaAttribute)ob).Name == attinfo.AttributeName)
435 memberSchema.Items.Add (GetSchemaAttribute (memberSchema, attinfo, false));
440 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember)
442 return GetSchemaElement (currentSchema, einfo, System.DBNull.Value,
443 isTypeMember, (XmlSchemaObjectContainer) null);
446 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, bool isTypeMember, XmlSchemaObjectContainer container)
448 return GetSchemaElement (currentSchema, einfo, System.DBNull.Value, isTypeMember, container);
451 XmlSchemaParticle GetSchemaElement (XmlSchema currentSchema, XmlTypeMapElementInfo einfo, object defaultValue, bool isTypeMember, XmlSchemaObjectContainer container)
453 if (einfo.IsTextElement) return null;
455 if (einfo.IsUnnamedAnyElement)
457 XmlSchemaAny any = new XmlSchemaAny ();
460 if (container != null)
461 container.Items.Add (any);
465 XmlSchemaElement selem = new XmlSchemaElement ();
466 if (container != null)
467 container.Items.Add (selem);
472 selem.MinOccurs = einfo.IsNullable ? 1 : 0;
474 if ((einfo.TypeData.IsValueType && einfo.Member != null && !einfo.Member.IsOptionalValueType) || encodedFormat)
478 XmlSchema memberSchema = null;
482 memberSchema = GetSchema (einfo.Namespace);
483 ImportNamespace (currentSchema, einfo.Namespace);
486 if (currentSchema == memberSchema || encodedFormat || !isTypeMember)
488 if (isTypeMember) selem.IsNillable = einfo.IsNullable;
489 selem.Name = einfo.ElementName;
491 if (defaultValue != System.DBNull.Value)
492 selem.DefaultValue = XmlCustomFormatter.ToXmlString (einfo.TypeData, defaultValue);
494 if (einfo.Form != XmlSchemaForm.Qualified)
495 selem.Form = einfo.Form;
497 switch (einfo.TypeData.SchemaType)
499 case SchemaTypes.XmlNode:
500 selem.SchemaType = GetSchemaXmlNodeType ();
503 case SchemaTypes.XmlSerializable:
504 selem.SchemaType = GetSchemaXmlSerializableType (einfo.MappedType as XmlSerializableMapping);
505 ExportXmlSerializableSchema (currentSchema, einfo.MappedType as XmlSerializableMapping);
508 case SchemaTypes.Enum:
509 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
510 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
511 ExportEnumSchema (einfo.MappedType);
514 case SchemaTypes.Array:
515 XmlQualifiedName atypeName = ExportArraySchema (einfo.MappedType, currentSchema.TargetNamespace);
516 selem.SchemaTypeName = atypeName;
517 ImportNamespace (currentSchema, atypeName.Namespace);
520 case SchemaTypes.Class:
521 if (einfo.MappedType.TypeData.Type != typeof(object)) {
522 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
523 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
525 else if (encodedFormat)
526 selem.SchemaTypeName = new XmlQualifiedName (einfo.MappedType.XmlType, einfo.MappedType.XmlTypeNamespace);
528 ExportClassSchema (einfo.MappedType);
531 case SchemaTypes.Primitive:
532 selem.SchemaTypeName = new XmlQualifiedName (einfo.TypeData.XmlType, einfo.DataTypeNamespace);
533 if (!einfo.TypeData.IsXsdType) {
534 ImportNamespace (currentSchema, einfo.MappedType.XmlTypeNamespace);
535 ExportDerivedSchema (einfo.MappedType);
542 selem.RefName = new XmlQualifiedName (einfo.ElementName, einfo.Namespace);
543 foreach (XmlSchemaObject ob in memberSchema.Items)
544 if (ob is XmlSchemaElement && ((XmlSchemaElement)ob).Name == einfo.ElementName)
547 GetSchemaElement (memberSchema, einfo, defaultValue, false,
548 new XmlSchemaObjectContainer (memberSchema));
553 void ImportNamespace (XmlSchema schema, string ns)
555 if (ns == null || ns.Length == 0 ||
556 ns == schema.TargetNamespace || ns == XmlSchema.Namespace) return;
558 foreach (XmlSchemaObject sob in schema.Includes)
559 if ((sob is XmlSchemaImport) && ((XmlSchemaImport)sob).Namespace == ns) return;
561 XmlSchemaImport imp = new XmlSchemaImport ();
563 schema.Includes.Add (imp);
566 bool DefinedInBaseMap (XmlTypeMapping map, XmlTypeMapMember member)
568 if (((ClassMap)map.ObjectMap).FindMember (member.Name) != null)
570 else if (map.BaseMap != null)
571 return DefinedInBaseMap (map.BaseMap, member);
576 XmlSchemaType GetSchemaXmlNodeType ()
578 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
579 stype.IsMixed = true;
580 XmlSchemaSequence seq = new XmlSchemaSequence ();
581 seq.Items.Add (new XmlSchemaAny ());
582 stype.Particle = seq;
586 XmlSchemaType GetSchemaXmlSerializableType (XmlSerializableMapping map)
588 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
589 XmlSchemaSequence seq = new XmlSchemaSequence ();
590 if (map.Schema == null) {
591 XmlSchemaElement selem = new XmlSchemaElement ();
592 selem.RefName = new XmlQualifiedName ("schema",XmlSchema.Namespace);
593 seq.Items.Add (selem);
594 seq.Items.Add (new XmlSchemaAny ());
596 XmlSchemaAny any = new XmlSchemaAny ();
597 any.Namespace = map.Schema.TargetNamespace;
600 stype.Particle = seq;
604 XmlSchemaSimpleType GetSchemaSimpleListType (TypeData typeData)
606 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
607 XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList ();
608 TypeData itemTypeData = TypeTranslator.GetTypeData (typeData.ListItemType);
609 list.ItemTypeName = new XmlQualifiedName (itemTypeData.XmlType, XmlSchema.Namespace);
610 stype.Content = list;
614 XmlSchemaParticle GetSchemaArrayElement (XmlSchema currentSchema, XmlTypeMapElementInfoList infos)
616 int numInfos = infos.Count;
617 if (numInfos > 0 && ((XmlTypeMapElementInfo)infos[0]).IsTextElement) numInfos--;
618 if (numInfos == 0) return null;
622 XmlSchemaParticle selem = GetSchemaElement (currentSchema, (XmlTypeMapElementInfo) infos[infos.Count-1], true);
623 selem.MinOccursString = "0";
624 selem.MaxOccursString = "unbounded";
629 XmlSchemaChoice schoice = new XmlSchemaChoice ();
630 schoice.MinOccursString = "0";
631 schoice.MaxOccursString = "unbounded";
632 foreach (XmlTypeMapElementInfo einfo in infos)
634 if (einfo.IsTextElement) continue;
635 schoice.Items.Add (GetSchemaElement (currentSchema, einfo, true));
641 void ExportDerivedSchema(XmlTypeMapping map) {
642 if (IsMapExported (map)) return;
643 SetMapExported (map);
645 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
646 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
647 stype.Name = map.ElementName;
648 schema.Items.Add (stype);
650 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
651 rest.BaseTypeName = new XmlQualifiedName (map.TypeData.MappedType.XmlType, XmlSchema.Namespace);
652 XmlSchemaPatternFacet facet = map.TypeData.XmlSchemaPatternFacet;
654 rest.Facets.Add(facet);
655 stype.Content = rest;
658 void ExportEnumSchema (XmlTypeMapping map)
660 if (IsMapExported (map)) return;
661 SetMapExported (map);
663 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
664 XmlSchemaSimpleType stype = new XmlSchemaSimpleType ();
665 stype.Name = map.ElementName;
666 schema.Items.Add (stype);
668 XmlSchemaSimpleTypeRestriction rest = new XmlSchemaSimpleTypeRestriction ();
669 rest.BaseTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
670 EnumMap emap = (EnumMap) map.ObjectMap;
672 foreach (EnumMap.EnumMapMember emem in emap.Members)
674 XmlSchemaEnumerationFacet ef = new XmlSchemaEnumerationFacet ();
675 ef.Value = emem.XmlName;
676 rest.Facets.Add (ef);
678 stype.Content = rest;
681 XmlQualifiedName ExportArraySchema (XmlTypeMapping map, string defaultNamespace)
683 ListMap lmap = (ListMap) map.ObjectMap;
687 string name, ns, schemaNs;
688 lmap.GetArrayType (-1, out name, out ns);
689 if (ns == XmlSchema.Namespace) schemaNs = defaultNamespace;
692 if (IsMapExported (map)) return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
693 SetMapExported (map);
695 XmlSchema schema = GetSchema (schemaNs);
696 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
697 stype.Name = lmap.GetSchemaArrayName ();
698 schema.Items.Add (stype);
700 XmlSchemaComplexContent content = new XmlSchemaComplexContent();
701 content.IsMixed = false;
702 stype.ContentModel = content;
704 XmlSchemaComplexContentRestriction rest = new XmlSchemaComplexContentRestriction ();
705 content.Content = rest;
706 rest.BaseTypeName = new XmlQualifiedName ("Array", XmlSerializer.EncodingNamespace);
707 XmlSchemaAttribute at = new XmlSchemaAttribute ();
708 rest.Attributes.Add (at);
709 at.RefName = new XmlQualifiedName ("arrayType", XmlSerializer.EncodingNamespace);
711 XmlAttribute arrayType = Document.CreateAttribute ("arrayType", XmlSerializer.WsdlNamespace);
712 arrayType.Value = ns + (ns != "" ? ":" : "") + name;
713 at.UnhandledAttributes = new XmlAttribute [] { arrayType };
714 ImportNamespace (schema, XmlSerializer.WsdlNamespace);
716 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) lmap.ItemInfo[0];
717 if (einfo.MappedType != null)
719 switch (einfo.TypeData.SchemaType)
721 case SchemaTypes.Enum:
722 ExportEnumSchema (einfo.MappedType);
724 case SchemaTypes.Array:
725 ExportArraySchema (einfo.MappedType, schemaNs);
727 case SchemaTypes.Class:
728 ExportClassSchema (einfo.MappedType);
733 return new XmlQualifiedName (lmap.GetSchemaArrayName (), schemaNs);
737 if (IsMapExported (map)) return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
739 SetMapExported (map);
740 XmlSchema schema = GetSchema (map.XmlTypeNamespace);
741 XmlSchemaComplexType stype = new XmlSchemaComplexType ();
742 stype.Name = map.ElementName;
743 schema.Items.Add (stype);
745 XmlSchemaParticle spart = GetSchemaArrayElement (schema, lmap.ItemInfo);
746 if (spart is XmlSchemaChoice)
747 stype.Particle = spart;
750 XmlSchemaSequence seq = new XmlSchemaSequence ();
751 seq.Items.Add (spart);
752 stype.Particle = seq;
755 return new XmlQualifiedName (map.XmlType, map.XmlTypeNamespace);
763 if (xmlDoc == null) xmlDoc = new XmlDocument ();
768 bool IsMapExported (XmlTypeMapping map)
770 if (exportedMaps.ContainsKey (GetMapKey(map))) return true;
774 void SetMapExported (XmlTypeMapping map)
776 exportedMaps [GetMapKey(map)] = map;
779 bool IsElementExported (XmlTypeMapping map)
781 if (exportedElements.ContainsKey (GetMapKey(map))) return true;
782 if (map.TypeData.Type == typeof(object)) return true;
786 void SetElementExported (XmlTypeMapping map)
788 exportedElements [GetMapKey(map)] = map;
791 string GetMapKey (XmlTypeMapping map)
793 // Don't use type name for array types, since we can have different
794 // classes that represent the same array type (for example
795 // StringCollection and string[]).
797 if (map.TypeData.IsListType)
798 return GetArrayKeyName (map.TypeData) + " " + map.XmlType + " " + map.XmlTypeNamespace;
800 return map.TypeData.FullTypeName + " " + map.XmlType + " " + map.XmlTypeNamespace;
803 string GetArrayKeyName (TypeData td)
805 TypeData etd = td.ListItemTypeData;
806 return "*arrayof*" + (etd.IsListType ? GetArrayKeyName (etd) : etd.FullTypeName);
809 void CompileSchemas ()
811 // foreach (XmlSchema sc in schemas)
812 // sc.Compile (null);
815 XmlSchema GetSchema (string ns)
817 XmlSchema schema = schemas [ns];
820 schema = new XmlSchema ();
821 if (ns != null && ns.Length > 0)
822 schema.TargetNamespace = ns;
824 schema.ElementFormDefault = XmlSchemaForm.Qualified;
825 schemas.Add (schema);
830 #endregion // Methods
832 private class XmlSchemaObjectContainer
834 private readonly XmlSchemaObject _xmlSchemaObject;
836 public XmlSchemaObjectContainer (XmlSchema schema)
838 _xmlSchemaObject = schema;
841 public XmlSchemaObjectContainer (XmlSchemaGroupBase group)
843 _xmlSchemaObject = group;
846 public XmlSchemaObjectCollection Items {
848 if (_xmlSchemaObject is XmlSchema) {
849 return ((XmlSchema) _xmlSchemaObject).Items;
851 return ((XmlSchemaGroupBase) _xmlSchemaObject).Items;