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 ();
73 [MonoNotSupported("")]
74 public string ExportAnyType (XmlMembersMapping members
)
76 throw new NotImplementedException ();
80 public void ExportMembersMapping (XmlMembersMapping xmlMembersMapping
)
82 ExportMembersMapping (xmlMembersMapping
, true);
90 void ExportMembersMapping (XmlMembersMapping xmlMembersMapping
, bool exportEnclosingType
)
92 ClassMap cmap
= (ClassMap
) xmlMembersMapping
.ObjectMap
;
94 if (xmlMembersMapping
.HasWrapperElement
&& exportEnclosingType
)
96 XmlSchema schema
= GetSchema (xmlMembersMapping
.Namespace
);
97 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
99 XmlSchemaSequence particle
;
100 XmlSchemaAnyAttribute anyAttribute
;
101 ExportMembersMapSchema (schema
, cmap
, null, stype
.Attributes
, out particle
, out anyAttribute
);
102 stype
.Particle
= particle
;
103 stype
.AnyAttribute
= anyAttribute
;
107 stype
.Name
= xmlMembersMapping
.ElementName
;
108 schema
.Items
.Add (stype
);
112 XmlSchemaElement selem
= new XmlSchemaElement ();
113 selem
.Name
= xmlMembersMapping
.ElementName
;
114 selem
.SchemaType
= stype
;
115 schema
.Items
.Add (selem
);
120 ICollection members
= cmap
.ElementMembers
;
123 foreach (XmlTypeMapMemberElement member
in members
)
125 if (member
is XmlTypeMapMemberAnyElement
&& member
.TypeData
.IsListType
)
127 XmlSchema mschema
= GetSchema (xmlMembersMapping
.Namespace
);
128 XmlSchemaParticle par
= GetSchemaArrayElement (mschema
, member
.ElementInfo
);
129 if (par
is XmlSchemaAny
)
131 XmlSchemaComplexType ct
= FindComplexType (mschema
.Items
, "any");
132 if (ct
!= null) continue;
134 ct
= new XmlSchemaComplexType ();
137 XmlSchemaSequence seq
= new XmlSchemaSequence ();
140 mschema
.Items
.Add (ct
);
146 XmlTypeMapElementInfo einfo
= (XmlTypeMapElementInfo
) member
.ElementInfo
[0];
151 schema
= GetSchema (xmlMembersMapping
.Namespace
);
152 ImportNamespace (schema
, XmlSerializer
.EncodingNamespace
);
155 schema
= GetSchema (einfo
.Namespace
);
158 XmlSchemaElement exe
= FindElement (schema
.Items
, einfo
.ElementName
);
159 XmlSchemaElement elem
;
161 XmlSchemaObjectContainer container
= null;
162 // In encoded format, the schema elements are not needed
164 container
= new XmlSchemaObjectContainer (schema
);
166 Type memType
= member
.GetType();
167 if (member
is XmlTypeMapMemberFlatList
)
168 throw new InvalidOperationException ("Unwrapped arrays not supported as parameters");
169 else if (memType
== typeof(XmlTypeMapMemberElement
))
170 elem
= (XmlSchemaElement
) GetSchemaElement (schema
,
171 einfo
, member
.DefaultValue
, false, container
);
173 elem
= (XmlSchemaElement
) GetSchemaElement (schema
,
174 einfo
, false, container
);
178 if (exe
.SchemaTypeName
.Equals (elem
.SchemaTypeName
))
179 schema
.Items
.Remove (elem
);
182 string s
= "The XML element named '" + einfo
.ElementName
+ "' ";
183 s
+= "from namespace '" + schema
.TargetNamespace
+ "' references distinct types " + elem
.SchemaTypeName
.Name
+ " and " + exe
.SchemaTypeName
.Name
+ ". ";
184 s
+= "Use XML attributes to specify another XML name or namespace for the element or types.";
185 throw new InvalidOperationException (s
);
196 public XmlQualifiedName
ExportTypeMapping (XmlMembersMapping xmlMembersMapping
)
198 throw new NotImplementedException ();
201 public void ExportTypeMapping (XmlTypeMapping xmlTypeMapping
)
203 if (!xmlTypeMapping
.IncludeInSchema
) return;
204 if (IsElementExported (xmlTypeMapping
)) return;
208 ExportClassSchema (xmlTypeMapping
);
209 XmlSchema schema
= GetSchema (xmlTypeMapping
.XmlTypeNamespace
);
210 ImportNamespace (schema
, XmlSerializer
.EncodingNamespace
);
214 XmlSchema schema
= GetSchema (xmlTypeMapping
.Namespace
);
215 XmlTypeMapElementInfo einfo
= new XmlTypeMapElementInfo (null, xmlTypeMapping
.TypeData
);
216 einfo
.Namespace
= xmlTypeMapping
.Namespace
;
217 einfo
.ElementName
= xmlTypeMapping
.ElementName
;
218 if (xmlTypeMapping
.TypeData
.IsComplexType
)
219 einfo
.MappedType
= xmlTypeMapping
;
220 einfo
.IsNullable
= xmlTypeMapping
.IsNullable
;
221 GetSchemaElement (schema
, einfo
, false, new XmlSchemaObjectContainer (schema
));
222 SetElementExported (xmlTypeMapping
);
228 void ExportXmlSerializableSchema (XmlSchema currentSchema
, XmlSerializableMapping map
)
230 if (IsMapExported (map
)) return;
231 SetMapExported (map
);
233 if (map
.Schema
== null) return;
235 string targetNs
= map
.Schema
.TargetNamespace
;
236 XmlSchema existingSchema
= schemas
[targetNs
];
237 if (existingSchema
== null)
239 schemas
.Add (map
.Schema
);
240 ImportNamespace (currentSchema
, targetNs
);
242 else if (existingSchema
!= map
.Schema
&& !CanBeDuplicated (existingSchema
, map
.Schema
))
244 throw new InvalidOperationException("The namespace '" + targetNs
+"' defined by the class '" + map
.TypeFullName
+ "' is a duplicate.");
248 private static bool CanBeDuplicated (XmlSchema existingSchema
, XmlSchema schema
)
250 if(XmlSchemas
.IsDataSet (existingSchema
) && XmlSchemas
.IsDataSet (schema
)
251 && existingSchema
.Id
== schema
.Id
)
256 void ExportClassSchema (XmlTypeMapping map
)
258 if (IsMapExported (map
)) return;
259 SetMapExported (map
);
261 if (map
.TypeData
.Type
== typeof(object))
263 foreach (XmlTypeMapping dmap
in map
.DerivedTypes
)
264 if (dmap
.TypeData
.SchemaType
== SchemaTypes
.Class
) ExportClassSchema (dmap
);
268 XmlSchema schema
= GetSchema (map
.XmlTypeNamespace
);
269 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
270 stype
.Name
= map
.XmlType
;
271 schema
.Items
.Add (stype
);
273 ClassMap cmap
= (ClassMap
)map
.ObjectMap
;
275 if (cmap
.HasSimpleContent
)
277 XmlSchemaSimpleContent simple
= new XmlSchemaSimpleContent ();
278 stype
.ContentModel
= simple
;
279 XmlSchemaSimpleContentExtension ext
= new XmlSchemaSimpleContentExtension ();
280 simple
.Content
= ext
;
281 XmlSchemaSequence particle
;
282 XmlSchemaAnyAttribute anyAttribute
;
283 ExportMembersMapSchema (schema
, cmap
, map
.BaseMap
, ext
.Attributes
, out particle
, out anyAttribute
);
284 ext
.AnyAttribute
= anyAttribute
;
285 if (map
.BaseMap
== null)
286 ext
.BaseTypeName
= cmap
.SimpleContentBaseType
;
288 ext
.BaseTypeName
= new XmlQualifiedName (map
.BaseMap
.XmlType
, map
.BaseMap
.XmlTypeNamespace
);
289 ImportNamespace (schema
, map
.BaseMap
.XmlTypeNamespace
);
290 ExportClassSchema (map
.BaseMap
);
293 else if (map
.BaseMap
!= null && map
.BaseMap
.IncludeInSchema
)
295 XmlSchemaComplexContent cstype
= new XmlSchemaComplexContent ();
296 XmlSchemaComplexContentExtension ext
= new XmlSchemaComplexContentExtension ();
297 ext
.BaseTypeName
= new XmlQualifiedName (map
.BaseMap
.XmlType
, map
.BaseMap
.XmlTypeNamespace
);
298 cstype
.Content
= ext
;
299 stype
.ContentModel
= cstype
;
301 XmlSchemaSequence particle
;
302 XmlSchemaAnyAttribute anyAttribute
;
303 ExportMembersMapSchema (schema
, cmap
, map
.BaseMap
, ext
.Attributes
, out particle
, out anyAttribute
);
304 ext
.Particle
= particle
;
305 ext
.AnyAttribute
= anyAttribute
;
306 stype
.IsMixed
= HasMixedContent (map
);
307 cstype
.IsMixed
= BaseHasMixedContent (map
);
309 ImportNamespace (schema
, map
.BaseMap
.XmlTypeNamespace
);
310 ExportClassSchema (map
.BaseMap
);
314 XmlSchemaSequence particle
;
315 XmlSchemaAnyAttribute anyAttribute
;
316 ExportMembersMapSchema (schema
, cmap
, map
.BaseMap
, stype
.Attributes
, out particle
, out anyAttribute
);
317 stype
.Particle
= particle
;
318 stype
.AnyAttribute
= anyAttribute
;
319 stype
.IsMixed
= cmap
.XmlTextCollector
!= null;
322 foreach (XmlTypeMapping dmap
in map
.DerivedTypes
)
323 if (dmap
.TypeData
.SchemaType
== SchemaTypes
.Class
) ExportClassSchema (dmap
);
326 bool BaseHasMixedContent (XmlTypeMapping map
)
328 ClassMap cmap
= (ClassMap
)map
.ObjectMap
;
329 return (cmap
.XmlTextCollector
!= null && (map
.BaseMap
!= null && DefinedInBaseMap (map
.BaseMap
, cmap
.XmlTextCollector
)));
332 bool HasMixedContent (XmlTypeMapping map
)
334 ClassMap cmap
= (ClassMap
)map
.ObjectMap
;
335 return (cmap
.XmlTextCollector
!= null && (map
.BaseMap
== null || !DefinedInBaseMap (map
.BaseMap
, cmap
.XmlTextCollector
)));
338 void ExportMembersMapSchema (XmlSchema schema
, ClassMap map
, XmlTypeMapping baseMap
, XmlSchemaObjectCollection outAttributes
, out XmlSchemaSequence particle
, out XmlSchemaAnyAttribute anyAttribute
)
341 XmlSchemaSequence seq
= new XmlSchemaSequence ();
343 ICollection members
= map
.ElementMembers
;
344 if (members
!= null && !map
.HasSimpleContent
)
346 foreach (XmlTypeMapMemberElement member
in members
)
348 if (baseMap
!= null && DefinedInBaseMap (baseMap
, member
)) continue;
350 Type memType
= member
.GetType();
351 if (memType
== typeof(XmlTypeMapMemberFlatList
))
353 XmlSchemaParticle part
= GetSchemaArrayElement (schema
, member
.ElementInfo
);
354 if (part
!= null) seq
.Items
.Add (part
);
356 else if (memType
== typeof(XmlTypeMapMemberAnyElement
))
358 seq
.Items
.Add (GetSchemaArrayElement (schema
, member
.ElementInfo
));
360 else if (memType
== typeof(XmlTypeMapMemberElement
))
362 GetSchemaElement (schema
, (XmlTypeMapElementInfo
) member
.ElementInfo
[0],
363 member
.DefaultValue
, true, new XmlSchemaObjectContainer (seq
));
367 GetSchemaElement (schema
, (XmlTypeMapElementInfo
) member
.ElementInfo
[0],
368 true, new XmlSchemaObjectContainer (seq
));
373 if (seq
.Items
.Count
> 0)
378 ICollection attributes
= map
.AttributeMembers
;
379 if (attributes
!= null)
381 foreach (XmlTypeMapMemberAttribute attr
in attributes
) {
382 if (baseMap
!= null && DefinedInBaseMap (baseMap
, attr
)) continue;
383 outAttributes
.Add (GetSchemaAttribute (schema
, attr
, true));
387 XmlTypeMapMember anyAttrMember
= map
.DefaultAnyAttributeMember
;
388 if (anyAttrMember
!= null)
389 anyAttribute
= new XmlSchemaAnyAttribute ();
394 XmlSchemaElement
FindElement (XmlSchemaObjectCollection col
, string name
)
396 foreach (XmlSchemaObject ob
in col
)
398 XmlSchemaElement elem
= ob
as XmlSchemaElement
;
399 if (elem
!= null && elem
.Name
== name
) return elem
;
404 XmlSchemaComplexType
FindComplexType (XmlSchemaObjectCollection col
, string name
)
406 foreach (XmlSchemaObject ob
in col
)
408 XmlSchemaComplexType ctype
= ob
as XmlSchemaComplexType
;
409 if (ctype
!= null && ctype
.Name
== name
) return ctype
;
414 XmlSchemaAttribute
GetSchemaAttribute (XmlSchema currentSchema
, XmlTypeMapMemberAttribute attinfo
, bool isTypeMember
)
416 XmlSchemaAttribute sat
= new XmlSchemaAttribute ();
417 if (attinfo
.DefaultValue
!= System
.DBNull
.Value
) {
418 sat
.DefaultValue
= ExportDefaultValue (attinfo
.TypeData
,
419 attinfo
.MappedType
, attinfo
.DefaultValue
);
421 if (!attinfo
.IsOptionalValueType
&& attinfo
.TypeData
.IsValueType
)
422 sat
.Use
= XmlSchemaUse
.Required
;
425 ImportNamespace (currentSchema
, attinfo
.Namespace
);
427 XmlSchema memberSchema
;
428 if (attinfo
.Namespace
.Length
== 0 && attinfo
.Form
!= XmlSchemaForm
.Qualified
)
429 memberSchema
= currentSchema
;
431 memberSchema
= GetSchema (attinfo
.Namespace
);
433 if (currentSchema
== memberSchema
|| encodedFormat
)
435 sat
.Name
= attinfo
.AttributeName
;
436 if (isTypeMember
) sat
.Form
= attinfo
.Form
;
437 if (attinfo
.TypeData
.SchemaType
== SchemaTypes
.Enum
)
439 ImportNamespace (currentSchema
, attinfo
.DataTypeNamespace
);
440 ExportEnumSchema (attinfo
.MappedType
);
441 sat
.SchemaTypeName
= new XmlQualifiedName (attinfo
.TypeData
.XmlType
, attinfo
.DataTypeNamespace
);
443 else if (attinfo
.TypeData
.SchemaType
== SchemaTypes
.Array
&& TypeTranslator
.IsPrimitive (attinfo
.TypeData
.ListItemType
))
445 sat
.SchemaType
= GetSchemaSimpleListType (attinfo
.TypeData
);
448 sat
.SchemaTypeName
= new XmlQualifiedName (attinfo
.TypeData
.XmlType
, attinfo
.DataTypeNamespace
);;
452 sat
.RefName
= new XmlQualifiedName (attinfo
.AttributeName
, attinfo
.Namespace
);
453 foreach (XmlSchemaObject ob
in memberSchema
.Items
)
454 if (ob
is XmlSchemaAttribute
&& ((XmlSchemaAttribute
)ob
).Name
== attinfo
.AttributeName
)
457 memberSchema
.Items
.Add (GetSchemaAttribute (memberSchema
, attinfo
, false));
462 XmlSchemaParticle
GetSchemaElement (XmlSchema currentSchema
, XmlTypeMapElementInfo einfo
, bool isTypeMember
)
464 return GetSchemaElement (currentSchema
, einfo
, System
.DBNull
.Value
,
465 isTypeMember
, (XmlSchemaObjectContainer
) null);
468 XmlSchemaParticle
GetSchemaElement (XmlSchema currentSchema
, XmlTypeMapElementInfo einfo
, bool isTypeMember
, XmlSchemaObjectContainer container
)
470 return GetSchemaElement (currentSchema
, einfo
, System
.DBNull
.Value
, isTypeMember
, container
);
473 XmlSchemaParticle
GetSchemaElement (XmlSchema currentSchema
, XmlTypeMapElementInfo einfo
, object defaultValue
, bool isTypeMember
, XmlSchemaObjectContainer container
)
475 if (einfo
.IsTextElement
) return null;
477 if (einfo
.IsUnnamedAnyElement
)
479 XmlSchemaAny any
= new XmlSchemaAny ();
482 if (container
!= null)
483 container
.Items
.Add (any
);
487 XmlSchemaElement selem
= new XmlSchemaElement ();
488 selem
.IsNillable
= einfo
.IsNullable
;
489 if (container
!= null)
490 container
.Items
.Add (selem
);
495 selem
.MinOccurs
= einfo
.IsNullable
? 1 : 0;
497 if ((defaultValue
== DBNull
.Value
&& einfo
.TypeData
.IsValueType
&& einfo
.Member
!= null && !einfo
.Member
.IsOptionalValueType
) || encodedFormat
)
501 XmlSchema memberSchema
= null;
505 memberSchema
= GetSchema (einfo
.Namespace
);
506 ImportNamespace (currentSchema
, einfo
.Namespace
);
509 if (currentSchema
== memberSchema
|| encodedFormat
|| !isTypeMember
)
511 if (isTypeMember
) selem
.IsNillable
= einfo
.IsNullable
;
512 selem
.Name
= einfo
.ElementName
;
514 if (defaultValue
!= System
.DBNull
.Value
)
515 selem
.DefaultValue
= ExportDefaultValue (einfo
.TypeData
,
516 einfo
.MappedType
, defaultValue
);
518 if (einfo
.Form
!= XmlSchemaForm
.Qualified
)
519 selem
.Form
= einfo
.Form
;
521 switch (einfo
.TypeData
.SchemaType
)
523 case SchemaTypes
.XmlNode
:
524 selem
.SchemaType
= GetSchemaXmlNodeType ();
527 case SchemaTypes
.XmlSerializable
:
528 SetSchemaXmlSerializableType (einfo
.MappedType
as XmlSerializableMapping
, selem
);
529 ExportXmlSerializableSchema (currentSchema
, einfo
.MappedType
as XmlSerializableMapping
);
532 case SchemaTypes
.Enum
:
533 selem
.SchemaTypeName
= new XmlQualifiedName (einfo
.MappedType
.XmlType
, einfo
.MappedType
.XmlTypeNamespace
);
534 ImportNamespace (currentSchema
, einfo
.MappedType
.XmlTypeNamespace
);
535 ExportEnumSchema (einfo
.MappedType
);
538 case SchemaTypes
.Array
:
539 XmlQualifiedName atypeName
= ExportArraySchema (einfo
.MappedType
, currentSchema
.TargetNamespace
);
540 selem
.SchemaTypeName
= atypeName
;
541 ImportNamespace (currentSchema
, atypeName
.Namespace
);
544 case SchemaTypes
.Class
:
545 if (einfo
.MappedType
.TypeData
.Type
!= typeof(object)) {
546 selem
.SchemaTypeName
= new XmlQualifiedName (einfo
.MappedType
.XmlType
, einfo
.MappedType
.XmlTypeNamespace
);
547 ImportNamespace (currentSchema
, einfo
.MappedType
.XmlTypeNamespace
);
549 else if (encodedFormat
)
550 selem
.SchemaTypeName
= new XmlQualifiedName (einfo
.MappedType
.XmlType
, einfo
.MappedType
.XmlTypeNamespace
);
552 ExportClassSchema (einfo
.MappedType
);
555 case SchemaTypes
.Primitive
:
556 selem
.SchemaTypeName
= new XmlQualifiedName (einfo
.TypeData
.XmlType
, einfo
.DataTypeNamespace
);
557 if (!einfo
.TypeData
.IsXsdType
) {
558 ImportNamespace (currentSchema
, einfo
.MappedType
.XmlTypeNamespace
);
559 ExportDerivedSchema (einfo
.MappedType
);
566 selem
.RefName
= new XmlQualifiedName (einfo
.ElementName
, einfo
.Namespace
);
567 foreach (XmlSchemaObject ob
in memberSchema
.Items
)
568 if (ob
is XmlSchemaElement
&& ((XmlSchemaElement
)ob
).Name
== einfo
.ElementName
)
571 GetSchemaElement (memberSchema
, einfo
, defaultValue
, false,
572 new XmlSchemaObjectContainer (memberSchema
));
577 void ImportNamespace (XmlSchema schema
, string ns
)
579 if (ns
== null || ns
.Length
== 0 ||
580 ns
== schema
.TargetNamespace
|| ns
== XmlSchema
.Namespace
) return;
582 foreach (XmlSchemaObject sob
in schema
.Includes
)
583 if ((sob
is XmlSchemaImport
) && ((XmlSchemaImport
)sob
).Namespace
== ns
) return;
585 XmlSchemaImport imp
= new XmlSchemaImport ();
587 schema
.Includes
.Add (imp
);
590 bool DefinedInBaseMap (XmlTypeMapping map
, XmlTypeMapMember member
)
592 if (((ClassMap
)map
.ObjectMap
).FindMember (member
.Name
) != null)
594 else if (map
.BaseMap
!= null)
595 return DefinedInBaseMap (map
.BaseMap
, member
);
600 XmlSchemaType
GetSchemaXmlNodeType ()
602 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
603 stype
.IsMixed
= true;
604 XmlSchemaSequence seq
= new XmlSchemaSequence ();
605 seq
.Items
.Add (new XmlSchemaAny ());
606 stype
.Particle
= seq
;
610 void SetSchemaXmlSerializableType (XmlSerializableMapping map
, XmlSchemaElement elem
)
613 if (map
.SchemaType
!= null && map
.Schema
!= null) {
614 elem
.SchemaType
= map
.SchemaType
;
618 if (map
.SchemaType
== null && map
.SchemaTypeName
!= null) {
619 elem
.SchemaTypeName
= map
.SchemaTypeName
;
620 elem
.Name
= map
.SchemaTypeName
.Name
;
624 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
625 XmlSchemaSequence seq
= new XmlSchemaSequence ();
626 if (map
.Schema
== null) {
627 XmlSchemaElement selem
= new XmlSchemaElement ();
628 selem
.RefName
= new XmlQualifiedName ("schema",XmlSchema
.Namespace
);
629 seq
.Items
.Add (selem
);
630 seq
.Items
.Add (new XmlSchemaAny ());
632 XmlSchemaAny any
= new XmlSchemaAny ();
633 any
.Namespace
= map
.Schema
.TargetNamespace
;
636 stype
.Particle
= seq
;
637 elem
.SchemaType
= stype
;
640 XmlSchemaSimpleType
GetSchemaSimpleListType (TypeData typeData
)
642 XmlSchemaSimpleType stype
= new XmlSchemaSimpleType ();
643 XmlSchemaSimpleTypeList list
= new XmlSchemaSimpleTypeList ();
644 TypeData itemTypeData
= TypeTranslator
.GetTypeData (typeData
.ListItemType
);
645 list
.ItemTypeName
= new XmlQualifiedName (itemTypeData
.XmlType
, XmlSchema
.Namespace
);
646 stype
.Content
= list
;
650 XmlSchemaParticle
GetSchemaArrayElement (XmlSchema currentSchema
, XmlTypeMapElementInfoList infos
)
652 int numInfos
= infos
.Count
;
653 if (numInfos
> 0 && ((XmlTypeMapElementInfo
)infos
[0]).IsTextElement
) numInfos
--;
654 if (numInfos
== 0) return null;
658 XmlSchemaParticle selem
= GetSchemaElement (currentSchema
, (XmlTypeMapElementInfo
) infos
[infos
.Count
-1], true);
659 selem
.MinOccursString
= "0";
660 selem
.MaxOccursString
= "unbounded";
665 XmlSchemaChoice schoice
= new XmlSchemaChoice ();
666 schoice
.MinOccursString
= "0";
667 schoice
.MaxOccursString
= "unbounded";
668 foreach (XmlTypeMapElementInfo einfo
in infos
)
670 if (einfo
.IsTextElement
) continue;
671 schoice
.Items
.Add (GetSchemaElement (currentSchema
, einfo
, true));
677 string ExportDefaultValue (TypeData typeData
, XmlTypeMapping map
, object defaultValue
)
679 if (typeData
.SchemaType
== SchemaTypes
.Enum
) {
680 EnumMap enumMap
= (EnumMap
) map
.ObjectMap
;
681 // get corresponding xml name
682 return enumMap
.GetXmlName (map
.TypeFullName
, defaultValue
);
684 return XmlCustomFormatter
.ToXmlString (typeData
, defaultValue
);
687 void ExportDerivedSchema(XmlTypeMapping map
) {
688 if (IsMapExported (map
)) return;
689 SetMapExported (map
);
691 XmlSchema schema
= GetSchema (map
.XmlTypeNamespace
);
692 for (int i
= 0; i
< schema
.Items
.Count
; i
++) {
693 XmlSchemaSimpleType item
= schema
.Items
[i
] as XmlSchemaSimpleType
;
694 if (item
!= null && item
.Name
== map
.ElementName
)
697 XmlSchemaSimpleType stype
= new XmlSchemaSimpleType ();
698 stype
.Name
= map
.ElementName
;
699 schema
.Items
.Add (stype
);
701 XmlSchemaSimpleTypeRestriction rest
= new XmlSchemaSimpleTypeRestriction ();
702 rest
.BaseTypeName
= new XmlQualifiedName (map
.TypeData
.MappedType
.XmlType
, XmlSchema
.Namespace
);
703 XmlSchemaPatternFacet facet
= map
.TypeData
.XmlSchemaPatternFacet
;
705 rest
.Facets
.Add(facet
);
706 stype
.Content
= rest
;
709 void ExportEnumSchema (XmlTypeMapping map
)
711 if (IsMapExported (map
)) return;
712 SetMapExported (map
);
714 XmlSchema schema
= GetSchema (map
.XmlTypeNamespace
);
715 XmlSchemaSimpleType stype
= new XmlSchemaSimpleType ();
716 stype
.Name
= map
.ElementName
;
717 schema
.Items
.Add (stype
);
719 XmlSchemaSimpleTypeRestriction rest
= new XmlSchemaSimpleTypeRestriction ();
720 rest
.BaseTypeName
= new XmlQualifiedName ("string",XmlSchema
.Namespace
);
721 EnumMap emap
= (EnumMap
) map
.ObjectMap
;
723 foreach (EnumMap
.EnumMapMember emem
in emap
.Members
)
725 XmlSchemaEnumerationFacet ef
= new XmlSchemaEnumerationFacet ();
726 ef
.Value
= emem
.XmlName
;
727 rest
.Facets
.Add (ef
);
731 XmlSchemaSimpleTypeList slist
= new XmlSchemaSimpleTypeList ();
732 XmlSchemaSimpleType restrictionType
= new XmlSchemaSimpleType ();
733 restrictionType
.Content
= rest
;
734 slist
.ItemType
= restrictionType
;
735 stype
.Content
= slist
;
737 stype
.Content
= rest
;
741 XmlQualifiedName
ExportArraySchema (XmlTypeMapping map
, string defaultNamespace
)
743 ListMap lmap
= (ListMap
) map
.ObjectMap
;
747 string name
, ns
, schemaNs
;
748 lmap
.GetArrayType (-1, out name
, out ns
);
749 if (ns
== XmlSchema
.Namespace
) schemaNs
= defaultNamespace
;
752 if (IsMapExported (map
)) return new XmlQualifiedName (lmap
.GetSchemaArrayName (), schemaNs
);
753 SetMapExported (map
);
755 XmlSchema schema
= GetSchema (schemaNs
);
756 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
757 stype
.Name
= lmap
.GetSchemaArrayName ();
758 schema
.Items
.Add (stype
);
760 XmlSchemaComplexContent content
= new XmlSchemaComplexContent();
761 content
.IsMixed
= false;
762 stype
.ContentModel
= content
;
764 XmlSchemaComplexContentRestriction rest
= new XmlSchemaComplexContentRestriction ();
765 content
.Content
= rest
;
766 rest
.BaseTypeName
= new XmlQualifiedName ("Array", XmlSerializer
.EncodingNamespace
);
767 XmlSchemaAttribute at
= new XmlSchemaAttribute ();
768 rest
.Attributes
.Add (at
);
769 at
.RefName
= new XmlQualifiedName ("arrayType", XmlSerializer
.EncodingNamespace
);
771 XmlAttribute arrayType
= Document
.CreateAttribute ("arrayType", XmlSerializer
.WsdlNamespace
);
772 arrayType
.Value
= ns
+ (ns
!= "" ? ":" : "") + name
;
773 at
.UnhandledAttributes
= new XmlAttribute
[] { arrayType }
;
774 ImportNamespace (schema
, XmlSerializer
.WsdlNamespace
);
776 XmlTypeMapElementInfo einfo
= (XmlTypeMapElementInfo
) lmap
.ItemInfo
[0];
777 if (einfo
.MappedType
!= null)
779 switch (einfo
.TypeData
.SchemaType
)
781 case SchemaTypes
.Enum
:
782 ExportEnumSchema (einfo
.MappedType
);
784 case SchemaTypes
.Array
:
785 ExportArraySchema (einfo
.MappedType
, schemaNs
);
787 case SchemaTypes
.Class
:
788 ExportClassSchema (einfo
.MappedType
);
793 return new XmlQualifiedName (lmap
.GetSchemaArrayName (), schemaNs
);
797 if (IsMapExported (map
)) return new XmlQualifiedName (map
.XmlType
, map
.XmlTypeNamespace
);
799 SetMapExported (map
);
800 XmlSchema schema
= GetSchema (map
.XmlTypeNamespace
);
801 XmlSchemaComplexType stype
= new XmlSchemaComplexType ();
802 stype
.Name
= map
.ElementName
;
803 schema
.Items
.Add (stype
);
805 XmlSchemaParticle spart
= GetSchemaArrayElement (schema
, lmap
.ItemInfo
);
806 if (spart
is XmlSchemaChoice
)
807 stype
.Particle
= spart
;
810 XmlSchemaSequence seq
= new XmlSchemaSequence ();
811 seq
.Items
.Add (spart
);
812 stype
.Particle
= seq
;
815 return new XmlQualifiedName (map
.XmlType
, map
.XmlTypeNamespace
);
823 if (xmlDoc
== null) xmlDoc
= new XmlDocument ();
828 bool IsMapExported (XmlTypeMapping map
)
830 if (exportedMaps
.ContainsKey (GetMapKey(map
))) return true;
834 void SetMapExported (XmlTypeMapping map
)
836 exportedMaps
[GetMapKey(map
)] = map
;
839 bool IsElementExported (XmlTypeMapping map
)
841 if (exportedElements
.ContainsKey (GetMapKey(map
))) return true;
842 if (map
.TypeData
.Type
== typeof(object)) return true;
846 void SetElementExported (XmlTypeMapping map
)
848 exportedElements
[GetMapKey(map
)] = map
;
851 string GetMapKey (XmlTypeMapping map
)
853 // Don't use type name for array types, since we can have different
854 // classes that represent the same array type (for example
855 // StringCollection and string[]).
857 if (map
.TypeData
.IsListType
)
858 return GetArrayKeyName (map
.TypeData
) + " " + map
.XmlType
+ " " + map
.XmlTypeNamespace
;
860 return map
.TypeData
.FullTypeName
+ " " + map
.XmlType
+ " " + map
.XmlTypeNamespace
;
863 string GetArrayKeyName (TypeData td
)
865 TypeData etd
= td
.ListItemTypeData
;
866 return "*arrayof*" + (etd
.IsListType
? GetArrayKeyName (etd
) : etd
.FullTypeName
);
869 void CompileSchemas ()
871 // foreach (XmlSchema sc in schemas)
872 // sc.Compile (null);
875 XmlSchema
GetSchema (string ns
)
877 XmlSchema schema
= schemas
[ns
];
880 schema
= new XmlSchema ();
881 if (ns
!= null && ns
.Length
> 0)
882 schema
.TargetNamespace
= ns
;
884 schema
.ElementFormDefault
= XmlSchemaForm
.Qualified
;
885 schemas
.Add (schema
);
890 #endregion // Methods
892 private class XmlSchemaObjectContainer
894 private readonly XmlSchemaObject _xmlSchemaObject
;
896 public XmlSchemaObjectContainer (XmlSchema schema
)
898 _xmlSchemaObject
= schema
;
901 public XmlSchemaObjectContainer (XmlSchemaGroupBase
group)
903 _xmlSchemaObject
= group;
906 public XmlSchemaObjectCollection Items
{
908 if (_xmlSchemaObject
is XmlSchema
) {
909 return ((XmlSchema
) _xmlSchemaObject
).Items
;
911 return ((XmlSchemaGroupBase
) _xmlSchemaObject
).Items
;