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 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
);
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
;
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
);
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
)
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);
325 seq
.Items
.Add (elem
);
329 seq
.Items
.Add (GetSchemaElement (schema
, (XmlTypeMapElementInfo
) member
.ElementInfo
[0], true));
334 if (seq
.Items
.Count
> 0)
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 ();
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
;
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
;
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
;
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
);
403 sat
.SchemaTypeName
= new XmlQualifiedName (attinfo
.TypeData
.XmlType
, attinfo
.DataTypeNamespace
);;
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
)
412 memberSchema
.Items
.Add (GetSchemaAttribute (memberSchema
, attinfo
, false));
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 ();
434 XmlSchemaElement selem
= new XmlSchemaElement ();
439 selem
.MinOccurs
= einfo
.IsNullable
? 1 : 0;
441 if ((einfo
.TypeData
.IsValueType
&& einfo
.Member
!= null && !einfo
.Member
.IsOptionalValueType
) || encodedFormat
)
445 XmlSchema memberSchema
= null;
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 ();
471 case SchemaTypes
.XmlSerializable
:
472 selem
.SchemaType
= GetSchemaXmlSerializableType ();
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
);
481 case SchemaTypes
.Array
:
482 XmlQualifiedName atypeName
= ExportArraySchema (einfo
.MappedType
, currentSchema
.TargetNamespace
);
483 selem
.SchemaTypeName
= atypeName
;
484 ImportNamespace (currentSchema
, atypeName
.Namespace
);
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
);
498 case SchemaTypes
.Primitive
:
499 selem
.SchemaTypeName
= new XmlQualifiedName (einfo
.TypeData
.XmlType
, einfo
.DataTypeNamespace
);;
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
)
510 memberSchema
.Items
.Add (GetSchemaElement (memberSchema
, einfo
, defaultValue
, false));
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 ();
524 schema
.Includes
.Add (imp
);
527 bool DefinedInBaseMap (XmlTypeMapping map
, XmlTypeMapMember member
)
529 if (((ClassMap
)map
.ObjectMap
).FindMember (member
.Name
) != null)
531 else if (map
.BaseMap
!= null)
532 return DefinedInBaseMap (map
.BaseMap
, member
);
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
;
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
;
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
;
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;
577 XmlSchemaParticle selem
= GetSchemaElement (currentSchema
, (XmlTypeMapElementInfo
) infos
[infos
.Count
-1], true);
578 selem
.MinOccursString
= "0";
579 selem
.MaxOccursString
= "unbounded";
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));
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
;
625 string name
, ns
, schemaNs
;
626 lmap
.GetArrayType (-1, out name
, out ns
);
627 if (ns
== XmlSchema
.Namespace
) schemaNs
= defaultNamespace
;
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
);
662 case SchemaTypes
.Array
:
663 ExportArraySchema (einfo
.MappedType
, schemaNs
);
665 case SchemaTypes
.Class
:
666 ExportClassSchema (einfo
.MappedType
);
671 return new XmlQualifiedName (lmap
.GetSchemaArrayName (), schemaNs
);
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
;
688 XmlSchemaSequence seq
= new XmlSchemaSequence ();
689 seq
.Items
.Add (spart
);
690 stype
.Particle
= seq
;
693 return new XmlQualifiedName (map
.XmlType
, map
.XmlTypeNamespace
);
701 if (xmlDoc
== null) xmlDoc
= new XmlDocument ();
706 bool IsMapExported (XmlTypeMapping map
)
708 if (exportedMaps
.ContainsKey (GetMapKey(map
))) return true;
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;
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
;
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
];
758 schema
= new XmlSchema ();
759 schema
.TargetNamespace
= ns
;
761 schema
.ElementFormDefault
= XmlSchemaForm
.Qualified
;
762 schemas
.Add (schema
);
767 #endregion // Methods