2 // System.Xml.Serialization.XmlSchemaImporter
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 #if !TARGET_JVM && !MOBILE
34 using System.CodeDom.Compiler;
36 using System.Xml.Schema;
37 using System.Collections;
38 using System.Collections.Generic;
39 #if NET_2_0 && CONFIGURATION_DEP
40 using System.Configuration;
41 using System.Xml.Serialization.Configuration;
44 namespace System.Xml.Serialization
46 public class XmlSchemaImporter
47 #if NET_2_0 && !MOBILE
54 CodeIdentifiers typeIdentifiers;
55 CodeIdentifiers elemIdentifiers = new CodeIdentifiers ();
56 Hashtable mappedTypes = new Hashtable ();
57 Hashtable primitiveDerivedMappedTypes = new Hashtable ();
58 Hashtable dataMappedTypes = new Hashtable ();
59 Queue pendingMaps = new Queue ();
60 Hashtable sharedAnonymousTypes = new Hashtable ();
61 bool encodedFormat = false;
62 XmlReflectionImporter auxXmlRefImporter;
63 SoapReflectionImporter auxSoapRefImporter;
66 // CodeGenerationOptions options;
68 static readonly XmlQualifiedName anyType = new XmlQualifiedName ("anyType",XmlSchema.Namespace);
69 static readonly XmlQualifiedName arrayType = new XmlQualifiedName ("Array",XmlSerializer.EncodingNamespace);
70 static readonly XmlQualifiedName arrayTypeRefName = new XmlQualifiedName ("arrayType",XmlSerializer.EncodingNamespace);
72 const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";
74 XmlSchemaElement anyElement = null;
78 public XmlTypeMapping Map;
79 public XmlSchemaComplexType SchemaType;
80 public XmlQualifiedName TypeName;
87 public XmlSchemaImporter (XmlSchemas schemas)
89 this.schemas = schemas;
90 typeIdentifiers = new CodeIdentifiers ();
92 InitializeExtensions ();
95 public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers)
98 this.typeIdentifiers = typeIdentifiers;
101 #if !TARGET_JVM && !MOBILE
103 public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, CodeDomProvider codeProvider, ImportContext context)
105 this.schemas = schemas;
106 // this.options = options;
107 if (context != null) {
108 typeIdentifiers = context.TypeIdentifiers;
109 InitSharedData (context);
112 typeIdentifiers = new CodeIdentifiers ();
114 InitializeExtensions ();
118 public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, ImportContext context)
120 this.schemas = schemas;
121 // this.options = options;
122 if (context != null) {
123 typeIdentifiers = context.TypeIdentifiers;
124 InitSharedData (context);
127 typeIdentifiers = new CodeIdentifiers ();
129 InitializeExtensions ();
133 public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers, CodeGenerationOptions options)
135 this.typeIdentifiers = typeIdentifiers;
136 this.schemas = schemas;
137 // this.options = options;
139 InitializeExtensions ();
142 void InitSharedData (ImportContext context)
144 if (context.ShareTypes) {
145 mappedTypes = context.MappedTypes;
146 dataMappedTypes = context.DataMappedTypes;
147 sharedAnonymousTypes = context.SharedAnonymousTypes;
152 internal bool UseEncodedFormat
154 get { return encodedFormat; }
155 set { encodedFormat = value; }
158 #endregion // Constructors
162 void InitializeExtensions ()
164 #if NET_2_0 && CONFIGURATION_DEP
165 SerializationSectionGroup root = ConfigurationManager.GetSection ("system.xml.serialization") as SerializationSectionGroup;
169 foreach (SchemaImporterExtensionElement element in
170 root.SchemaImporterExtensions.SchemaImporterExtensions)
171 Extensions.Add (element.Name, element.Type);
175 public XmlMembersMapping ImportAnyType (XmlQualifiedName typeName, string elementName)
177 if (typeName == XmlQualifiedName.Empty)
179 XmlTypeMapMemberAnyElement mapMem = new XmlTypeMapMemberAnyElement ();
180 mapMem.Name = typeName.Name;
181 mapMem.TypeData = TypeTranslator.GetTypeData(typeof(XmlNode));
182 mapMem.ElementInfo.Add (CreateElementInfo (typeName.Namespace, mapMem, typeName.Name, mapMem.TypeData, true, XmlSchemaForm.None, -1));
184 XmlMemberMapping[] mm = new XmlMemberMapping [1];
185 mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
186 return new XmlMembersMapping (mm);
190 XmlSchemaComplexType stype = (XmlSchemaComplexType) schemas.Find (typeName, typeof (XmlSchemaComplexType));
192 throw new InvalidOperationException ("Referenced type '" + typeName + "' not found");
194 if (!CanBeAnyElement (stype))
195 throw new InvalidOperationException ("The type '" + typeName + "' is not valid for a collection of any elements");
197 ClassMap cmap = new ClassMap ();
198 CodeIdentifiers classIds = new CodeIdentifiers ();
199 bool isMixed = stype.IsMixed;
200 ImportSequenceContent (typeName, cmap, ((XmlSchemaSequence) stype.Particle).Items, classIds, false, ref isMixed);
201 XmlTypeMapMemberAnyElement mapMem = (XmlTypeMapMemberAnyElement) cmap.AllMembers[0];
202 mapMem.Name = typeName.Name;
204 XmlMemberMapping[] mm = new XmlMemberMapping [1];
205 mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
206 return new XmlMembersMapping (mm);
210 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType)
212 return ImportDerivedTypeMapping (name, baseType, true);
215 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
217 XmlQualifiedName qname;
223 stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
224 if (stype == null) throw new InvalidOperationException ("Schema type '" + name + "' not found or not valid");
228 if (!LocateElement (name, out qname, out stype))
232 XmlTypeMapping map = GetRegisteredTypeMapping (qname, baseType);
235 // If the type has already been imported, make sure that the map
236 // has the requested base type
238 SetMapBaseType (map, baseType);
239 map.UpdateRoot (name);
243 map = CreateTypeMapping (qname, SchemaTypes.Class, name);
245 map.Documentation = GetDocumentation (stype);
246 RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
248 ClassMap cmap = new ClassMap ();
249 CodeIdentifiers classIds = new CodeIdentifiers ();
250 map.ObjectMap = cmap;
251 AddTextMember (qname, cmap, classIds);
255 SetMapBaseType (map, baseType);
260 void SetMapBaseType (XmlTypeMapping map, Type baseType)
262 // This method sets the base type for a given map.
263 // If the map already inherits from this type, it does nothing.
265 // Fiirst of all, check if the map already inherits from baseType
267 XmlTypeMapping topMap = null;
270 if (map.TypeData.Type == baseType)
276 // Does not have the requested base type.
277 // Then, get/create a map for that base type.
279 XmlTypeMapping baseMap = ReflectType (baseType);
281 // Add this map as a derived map of the base map
283 topMap.BaseMap = baseMap;
284 baseMap.DerivedTypes.Add (topMap);
285 baseMap.DerivedTypes.AddRange (topMap.DerivedTypes);
287 // Now add the base type fields to all derived maps
289 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
291 ClassMap cmap = (ClassMap)topMap.ObjectMap;
292 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
293 cmap.AddMember (member);
295 foreach (XmlTypeMapping derivedMap in topMap.DerivedTypes)
297 cmap = (ClassMap)derivedMap.ObjectMap;
298 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
299 cmap.AddMember (member);
303 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName name)
305 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
306 if (elem == null) throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");
308 XmlSchemaComplexType stype;
309 if (elem.SchemaType != null)
311 stype = elem.SchemaType as XmlSchemaComplexType;
315 if (elem.SchemaTypeName.IsEmpty) return null;
316 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
318 if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) return null;
319 throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
321 stype = type as XmlSchemaComplexType;
325 throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");
327 XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, name);
328 return new XmlMembersMapping (name.Name, name.Namespace, mapping);
331 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names)
333 XmlMemberMapping[] mapping = new XmlMemberMapping [names.Length];
334 for (int n=0; n<names.Length; n++)
336 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (names[n], typeof (XmlSchemaElement));
337 if (elem == null) throw new InvalidOperationException ("Schema element '" + names[n] + "' not found");
339 XmlQualifiedName typeQName = new XmlQualifiedName ("Message", names[n].Namespace);
341 TypeData td = GetElementTypeData (typeQName, elem, names[n], out tmap);
343 mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, elem.IsNillable, td, tmap, n);
346 return new XmlMembersMapping (mapping);
351 public XmlMembersMapping ImportMembersMapping (string name, string ns, SoapSchemaMember[] members)
353 throw new NotImplementedException ();
356 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName)
358 return ImportSchemaType (typeName, typeof (object));
361 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType)
363 return ImportSchemaType (typeName, typeof (object), false);
366 [MonoTODO ("baseType and baseTypeCanBeIndirect are ignored")]
367 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType, bool baseTypeCanBeIndirect)
369 XmlSchemaType stype =
370 (XmlSchemaType) schemas.Find (typeName, typeof (XmlSchemaComplexType)) ??
371 (XmlSchemaType) schemas.Find (typeName, typeof (XmlSchemaSimpleType));
372 return ImportTypeCommon (typeName, typeName, stype, true);
376 internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement)
378 XmlMemberMapping[] mapping = new XmlMemberMapping [members.Length];
379 for (int n=0; n<members.Length; n++)
381 TypeData td = GetTypeData (members[n].MemberType, null, false); // FIXME: isNullable could be true?
382 XmlTypeMapping tmap = GetTypeMapping (td);
383 mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, true, td, tmap, n);
386 return new XmlMembersMapping (name, ns, hasWrapperElement, false, mapping);
389 internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember member)
391 XmlSchemaComplexType stype = schemas.Find (member.MemberType, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
392 if (stype == null) throw new InvalidOperationException ("Schema type '" + member.MemberType + "' not found or not valid");
394 XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, member.MemberType);
395 return new XmlMembersMapping (name, ns, mapping);
398 XmlMemberMapping[] ImportMembersMappingComposite (XmlSchemaComplexType stype, XmlQualifiedName refer)
400 if (stype.Particle == null)
401 return new XmlMemberMapping [0];
403 ClassMap cmap = new ClassMap ();
405 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
406 if (seq == null) throw new InvalidOperationException ("Schema element '" + refer + "' cannot be imported as XmlMembersMapping");
408 CodeIdentifiers classIds = new CodeIdentifiers ();
409 ImportParticleComplexContent (refer, cmap, seq, classIds, false);
410 ImportAttributes (refer, cmap, stype.Attributes, stype.AnyAttribute, classIds);
415 XmlMemberMapping[] mapping = new XmlMemberMapping [cmap.AllMembers.Count];
416 foreach (XmlTypeMapMember mapMem in cmap.AllMembers)
417 mapping[n++] = new XmlMemberMapping (mapMem.Name, refer.Namespace, mapMem, encodedFormat);
422 XmlMemberMapping ImportMemberMapping (string name, string ns, bool isNullable, TypeData type, XmlTypeMapping emap, int order)
424 XmlTypeMapMemberElement mapMem;
427 mapMem = new XmlTypeMapMemberList ();
429 mapMem = new XmlTypeMapMemberElement ();
432 mapMem.TypeData = type;
433 mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, isNullable, XmlSchemaForm.None, emap, order));
434 return new XmlMemberMapping (name, ns, mapMem, encodedFormat);
438 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names, Type baseType, bool baseTypeCanBeIndirect)
440 throw new NotImplementedException ();
443 public XmlTypeMapping ImportTypeMapping (XmlQualifiedName name)
445 XmlQualifiedName qname;
448 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
449 if (!LocateElement (elem, out qname, out stype))
450 throw new InvalidOperationException (String.Format ("'{0}' is missing.", name));
451 return ImportTypeCommon (name, qname, stype, elem.IsNillable);
454 // FIXME: name and qname are confusing. Rename one either
455 // (name is in schema itself, qname is for actual processing.
456 // For example simple types have qname as in xsd namespace.)
457 private XmlTypeMapping ImportTypeCommon (XmlQualifiedName name, XmlQualifiedName qname, XmlSchemaType stype, bool isNullable)
460 if (qname == anyType) {
461 // Importing anyType.
462 XmlTypeMapping xmap = GetTypeMapping (TypeTranslator.GetTypeData (typeof (object)));
463 // This also means, all complexTypes
464 // are imported as well.
468 // Importing a primitive type
469 TypeData td = TypeTranslator.GetPrimitiveTypeData (qname.Name);
470 return ReflectType (td, name.Namespace);
474 XmlTypeMapping map = GetRegisteredTypeMapping (qname);
475 if (map != null) return map;
477 if (stype is XmlSchemaSimpleType)
478 return ImportClassSimpleType (stype.QualifiedName, (XmlSchemaSimpleType) stype, name);
480 map = CreateTypeMapping (qname, SchemaTypes.Class, name);
481 map.Documentation = GetDocumentation (stype);
482 map.IsNullable = isNullable;
483 RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
489 bool LocateElement (XmlQualifiedName name, out XmlQualifiedName qname, out XmlSchemaType stype)
491 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
492 return LocateElement (elem, out qname, out stype);
495 bool LocateElement (XmlSchemaElement elem, out XmlQualifiedName qname, out XmlSchemaType stype)
500 if (elem == null) return false;
502 // The root element must be an element with complex type
504 if (elem.SchemaType != null)
506 stype = elem.SchemaType;
507 qname = elem.QualifiedName;
509 else if (elem.ElementType == XmlSchemaComplexType.AnyType)
516 if (elem.SchemaTypeName.IsEmpty) return false;
518 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
519 if (type == null) type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaSimpleType));
521 if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) {
522 qname = elem.SchemaTypeName;
525 throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
527 stype = (XmlSchemaType) type;
528 qname = stype.QualifiedName;
530 XmlSchemaType btype = stype.BaseSchemaType as XmlSchemaType;
531 if (btype != null && btype.QualifiedName == elem.SchemaTypeName)
532 throw new InvalidOperationException ("Cannot import schema for type '" + elem.SchemaTypeName.Name + "' from namespace '" + elem.SchemaTypeName.Namespace + "'. Redefine not supported");
535 //if (stype is XmlSchemaSimpleType) return false;
539 XmlTypeMapping ImportType (XmlQualifiedName name, XmlQualifiedName root, bool throwOnError)
541 XmlTypeMapping map = GetRegisteredTypeMapping (name);
543 map.UpdateRoot (root);
547 XmlSchemaType type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaComplexType));
548 if (type == null) type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaSimpleType));
553 if (name.Namespace == XmlSerializer.EncodingNamespace)
554 throw new InvalidOperationException ("Referenced type '" + name + "' valid only for encoded SOAP.");
556 throw new InvalidOperationException ("Referenced type '" + name + "' not found.");
561 return ImportType (name, type, root);
564 XmlTypeMapping ImportClass (XmlQualifiedName name)
566 XmlTypeMapping map = ImportType (name, null, true);
567 if (map.TypeData.SchemaType == SchemaTypes.Class) return map;
568 XmlSchemaComplexType stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
569 return CreateClassMap (name, stype, new XmlQualifiedName (map.ElementName, map.Namespace));
572 XmlTypeMapping ImportType (XmlQualifiedName name, XmlSchemaType stype, XmlQualifiedName root)
574 XmlTypeMapping map = GetRegisteredTypeMapping (name);
576 XmlSchemaComplexType ct = stype as XmlSchemaComplexType;
577 if (map.TypeData.SchemaType != SchemaTypes.Class || ct == null || !CanBeArray (name, ct)) {
578 map.UpdateRoot (root);
582 // The map was initially imported as a class, but it turns out that it is an
583 // array. It has to be imported now as array.
586 if (stype is XmlSchemaComplexType)
587 return ImportClassComplexType (name, (XmlSchemaComplexType) stype, root);
588 else if (stype is XmlSchemaSimpleType)
589 return ImportClassSimpleType (name, (XmlSchemaSimpleType) stype, root);
591 throw new NotSupportedException ("Schema type not supported: " + stype.GetType ());
594 XmlTypeMapping ImportClassComplexType (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
596 // The need for fixups: If the complex type is an array, then to get the type of the
597 // array we need first to get the type of the items of the array.
598 // But if one of the item types or its children has a referece to this type array,
599 // then we enter in an infinite loop. This does not happen with class types because
600 // the class map is registered before parsing the children. We can't do the same
601 // with the array type because to register the array map we need the type of the array.
603 if (CanBeArray (typeQName, stype))
606 ListMap listMap = BuildArrayMap (typeQName, stype, out typeData);
609 XmlTypeMapping map = CreateArrayTypeMapping (typeQName, typeData);
610 map.ObjectMap = listMap;
614 // After all, it is not an array. Create a class map then.
616 else if (CanBeIXmlSerializable (stype))
618 return ImportXmlSerializableMapping (typeQName.Namespace);
621 // Register the map right now but do not build it,
622 // This will avoid loops.
624 return CreateClassMap (typeQName, stype, root);
627 XmlTypeMapping CreateClassMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
629 XmlTypeMapping map = CreateTypeMapping (typeQName, SchemaTypes.Class, root);
630 map.Documentation = GetDocumentation (stype);
631 RegisterMapFixup (map, typeQName, stype);
635 ArrayList fixup_registered_types = new ArrayList ();
637 void RegisterMapFixup (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
639 // This check is introduced for bug #650117, but might be too wide to catch erroneous cases...
640 if (fixup_registered_types.Contains (stype))
641 throw new InvalidOperationException (String.Format ("Circular dependency for schema type {0} in namespace {1}", map.ElementName, map.Namespace));
642 fixup_registered_types.Add (stype);
643 MapFixup fixup = new MapFixup ();
645 fixup.SchemaType = stype;
646 fixup.TypeName = typeQName;
647 pendingMaps.Enqueue (fixup);
650 void BuildPendingMaps ()
652 while (pendingMaps.Count > 0) {
653 MapFixup fixup = (MapFixup) pendingMaps.Dequeue ();
654 if (fixup.Map.ObjectMap == null) {
655 BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
656 if (fixup.Map.ObjectMap == null) pendingMaps.Enqueue (fixup);
661 void BuildPendingMap (XmlTypeMapping map)
663 if (map.ObjectMap != null) return;
665 foreach (MapFixup fixup in pendingMaps)
667 if (fixup.Map == map) {
668 BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
672 throw new InvalidOperationException ("Can't complete map of type " + map.XmlType + " : " + map.Namespace);
675 void BuildClassMap (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
677 CodeIdentifiers classIds = new CodeIdentifiers();
678 classIds.AddReserved (map.TypeData.TypeName);
680 ClassMap cmap = new ClassMap ();
681 map.ObjectMap = cmap;
682 bool isMixed = stype.IsMixed;
684 if (stype.Particle != null)
685 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, isMixed);
688 if (stype.ContentModel is XmlSchemaSimpleContent) {
689 ImportSimpleContent (typeQName, map, (XmlSchemaSimpleContent)stype.ContentModel, classIds, isMixed);
691 else if (stype.ContentModel is XmlSchemaComplexContent) {
692 ImportComplexContent (typeQName, map, (XmlSchemaComplexContent)stype.ContentModel, classIds, isMixed);
696 ImportAttributes (typeQName, cmap, stype.Attributes, stype.AnyAttribute, classIds);
697 ImportExtensionTypes (typeQName);
699 if (isMixed) AddTextMember (typeQName, cmap, classIds);
701 AddObjectDerivedMap (map);
704 void ImportAttributes (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat, CodeIdentifiers classIds)
706 atts = CollectAttributeUsesNonOverlap (atts, cmap);
710 XmlTypeMapMemberAnyAttribute member = new XmlTypeMapMemberAnyAttribute ();
711 member.Name = classIds.AddUnique ("AnyAttribute", member);
712 member.TypeData = TypeTranslator.GetTypeData (typeof(XmlAttribute[]));
713 cmap.AddMember (member);
716 foreach (XmlSchemaObject at in atts)
718 if (at is XmlSchemaAttribute)
721 XmlSchemaAttribute attr = (XmlSchemaAttribute)at;
722 XmlSchemaAttribute refAttr = GetRefAttribute (typeQName, attr, out ns);
723 XmlTypeMapMemberAttribute member = new XmlTypeMapMemberAttribute ();
724 member.Name = classIds.AddUnique (CodeIdentifier.MakeValid (refAttr.Name), member);
725 member.Documentation = GetDocumentation (attr);
726 member.AttributeName = refAttr.Name;
727 member.Namespace = ns;
728 member.Form = refAttr.Form;
729 member.TypeData = GetAttributeTypeData (typeQName, attr);
731 if (refAttr.DefaultValue != null)
732 member.DefaultValue = ImportDefaultValue (member.TypeData, refAttr.DefaultValue);
733 else if (member.TypeData.IsValueType)
734 member.IsOptionalValueType = (refAttr.ValidatedUse != XmlSchemaUse.Required);
736 if (member.TypeData.IsComplexType)
737 member.MappedType = GetTypeMapping (member.TypeData);
738 cmap.AddMember (member);
740 else if (at is XmlSchemaAttributeGroupRef)
742 XmlSchemaAttributeGroupRef gref = (XmlSchemaAttributeGroupRef)at;
743 XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
744 ImportAttributes (typeQName, cmap, grp.Attributes, grp.AnyAttribute, classIds);
749 IEnumerable<XmlSchemaAttribute> EnumerateAttributes (XmlSchemaObjectCollection col, List<XmlSchemaAttributeGroup> recurse)
751 foreach (var o in col) {
752 if (o is XmlSchemaAttributeGroupRef) {
753 var gr = (XmlSchemaAttributeGroupRef) o;
754 var g = FindRefAttributeGroup (gr.RefName);
755 if (recurse.Contains (g))
759 throw new InvalidOperationException (string.Format ("Referenced AttributeGroup '{0}' was not found.", gr.RefName));
760 foreach (var a in EnumerateAttributes (g.Attributes, recurse))
764 yield return (XmlSchemaAttribute) o;
768 // Attributes might be redefined, so there is an existing attribute for the same name, skip it.
769 // FIXME: this is nothing more than just a hack.
770 // Basically it should use
771 // XmlSchemaComplexType.AttributeUses.
772 XmlSchemaObjectCollection CollectAttributeUsesNonOverlap (
773 XmlSchemaObjectCollection src, ClassMap map)
775 XmlSchemaObjectCollection atts = new XmlSchemaObjectCollection ();
776 foreach (var a in EnumerateAttributes (src, new List<XmlSchemaAttributeGroup> ()))
777 if (map.GetAttribute (a.QualifiedName.Name, a.QualifiedName.Namespace) == null)
782 ListMap BuildArrayMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, out TypeData arrayTypeData)
786 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
787 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
788 XmlSchemaAttribute arrayTypeAt = FindArrayAttribute (rest.Attributes);
790 if (arrayTypeAt != null)
792 XmlAttribute[] uatts = arrayTypeAt.UnhandledAttributes;
793 if (uatts == null || uatts.Length == 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
795 XmlAttribute xat = null;
796 foreach (XmlAttribute at in uatts)
797 if (at.LocalName == "arrayType" && at.NamespaceURI == XmlSerializer.WsdlNamespace)
801 throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
803 string name, ns, dims;
804 TypeTranslator.ParseArrayType (xat.Value, out name, out ns, out dims);
805 return BuildEncodedArrayMap (name + dims, ns, out arrayTypeData);
809 XmlSchemaElement elem = null;
810 XmlSchemaSequence seq = rest.Particle as XmlSchemaSequence;
811 if (seq != null && seq.Items.Count == 1)
812 elem = seq.Items[0] as XmlSchemaElement;
814 XmlSchemaAll all = rest.Particle as XmlSchemaAll;
815 if (all != null && all.Items.Count == 1)
816 elem = all.Items[0] as XmlSchemaElement;
819 throw new InvalidOperationException ("Unknown array format");
821 return BuildEncodedArrayMap (elem.SchemaTypeName.Name + "[]", elem.SchemaTypeName.Namespace, out arrayTypeData);
826 ClassMap cmap = new ClassMap ();
827 CodeIdentifiers classIds = new CodeIdentifiers();
828 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, stype.IsMixed);
830 XmlTypeMapMemberFlatList list = (cmap.AllMembers.Count == 1) ? cmap.AllMembers[0] as XmlTypeMapMemberFlatList : null;
831 if (list != null && list.ChoiceMember == null)
833 arrayTypeData = list.TypeData;
838 arrayTypeData = null;
844 ListMap BuildEncodedArrayMap (string type, string ns, out TypeData arrayTypeData)
846 ListMap map = new ListMap ();
848 int i = type.LastIndexOf ("[");
849 if (i == -1) throw new InvalidOperationException ("Invalid arrayType value: " + type);
850 if (type.IndexOf (",",i) != -1) throw new InvalidOperationException ("Multidimensional arrays are not supported");
852 string itemType = type.Substring (0,i);
854 TypeData itemTypeData;
855 if (itemType.IndexOf ("[") != -1)
857 ListMap innerListMap = BuildEncodedArrayMap (itemType, ns, out itemTypeData);
859 int dims = itemType.Split ('[').Length - 1;
860 string name = TypeTranslator.GetArrayName (type, dims);
861 XmlQualifiedName qname = new XmlQualifiedName (name, ns);
862 XmlTypeMapping tmap = CreateArrayTypeMapping (qname, itemTypeData);
863 tmap.ObjectMap = innerListMap;
867 itemTypeData = GetTypeData (new XmlQualifiedName (itemType, ns), null, false);
870 arrayTypeData = itemTypeData.ListTypeData;
872 map.ItemInfo = new XmlTypeMapElementInfoList();
873 map.ItemInfo.Add (CreateElementInfo ("", null, "Item", itemTypeData, true, XmlSchemaForm.None, -1));
877 XmlSchemaAttribute FindArrayAttribute (XmlSchemaObjectCollection atts)
879 foreach (object ob in atts)
881 XmlSchemaAttribute att = ob as XmlSchemaAttribute;
882 if (att != null && att.RefName == arrayTypeRefName) return att;
884 XmlSchemaAttributeGroupRef gref = ob as XmlSchemaAttributeGroupRef;
887 XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
888 att = FindArrayAttribute (grp.Attributes);
889 if (att != null) return att;
895 void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)
897 ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);
898 if (isMixed) AddTextMember (typeQName, cmap, classIds);
901 void AddTextMember (XmlQualifiedName typeQName, ClassMap cmap, CodeIdentifiers classIds)
903 if (cmap.XmlTextCollector == null)
905 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
906 member.Name = classIds.AddUnique ("Text", member);
907 member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));
908 member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));
909 member.IsXmlTextCollector = true;
910 member.ListMap = new ListMap ();
911 member.ListMap.ItemInfo = member.ElementInfo;
912 cmap.AddMember (member);
916 void ImportParticleContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
918 if (particle == null) return;
920 if (particle is XmlSchemaGroupRef)
921 particle = GetRefGroupParticle ((XmlSchemaGroupRef)particle);
923 if (particle.MaxOccurs > 1) multiValue = true;
925 if (particle is XmlSchemaSequence) {
926 ImportSequenceContent (typeQName, cmap, ((XmlSchemaSequence)particle).Items, classIds, multiValue, ref isMixed);
928 else if (particle is XmlSchemaChoice) {
929 if (((XmlSchemaChoice)particle).Items.Count == 1)
930 ImportSequenceContent (typeQName, cmap, ((XmlSchemaChoice)particle).Items, classIds, multiValue, ref isMixed);
932 ImportChoiceContent (typeQName, cmap, (XmlSchemaChoice)particle, classIds, multiValue);
934 else if (particle is XmlSchemaAll) {
935 ImportSequenceContent (typeQName, cmap, ((XmlSchemaAll)particle).Items, classIds, multiValue, ref isMixed);
939 void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
941 foreach (XmlSchemaObject item in items)
943 if (item is XmlSchemaElement)
946 XmlSchemaElement elem = (XmlSchemaElement) item;
948 TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
949 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
951 if (elem.MaxOccurs == 1 && !multiValue)
953 XmlTypeMapMemberElement member = null;
954 if (typeData.SchemaType != SchemaTypes.Array)
956 member = new XmlTypeMapMemberElement ();
957 if (refElem.DefaultValue != null) member.DefaultValue = ImportDefaultValue (typeData, refElem.DefaultValue);
959 else if (GetTypeMapping (typeData).IsSimpleType)
961 // It is a simple list (space separated list).
962 // Since this is not supported, map as a single item value
963 member = new XmlTypeMapMemberElement ();
965 // In MS.NET those types are mapped to a string
966 typeData = TypeTranslator.GetTypeData(typeof(string));
968 typeData = typeData.ListItemTypeData;
972 member = new XmlTypeMapMemberList ();
974 if (elem.MinOccurs == 0 && typeData.IsValueType)
975 member.IsOptionalValueType = true;
977 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
978 member.Documentation = GetDocumentation (elem);
979 member.TypeData = typeData;
980 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item)));
981 cmap.AddMember (member);
985 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
986 member.ListMap = new ListMap ();
987 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
988 member.Documentation = GetDocumentation (elem);
989 member.TypeData = typeData.ListTypeData;
990 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, items.IndexOf (item)));
991 member.ListMap.ItemInfo = member.ElementInfo;
992 cmap.AddMember (member);
995 else if (item is XmlSchemaAny)
997 XmlSchemaAny elem = (XmlSchemaAny) item;
998 XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();
999 member.Name = classIds.AddUnique ("Any", member);
1000 member.Documentation = GetDocumentation (elem);
1003 if (elem.MaxOccurs != 1 || multiValue)
1004 ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);
1006 ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);
1008 member.TypeData = TypeTranslator.GetTypeData (ctype);
1009 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);
1010 einfo.IsUnnamedAnyElement = true;
1011 member.ElementInfo.Add (einfo);
1015 einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);
1016 member.ElementInfo.Add (einfo);
1017 member.IsXmlTextCollector = true;
1018 isMixed = false; //Allow only one XmlTextAttribute
1021 cmap.AddMember (member);
1023 else if (item is XmlSchemaParticle) {
1024 ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);
1029 object ImportDefaultValue (TypeData typeData, string value)
1031 if (typeData.SchemaType == SchemaTypes.Enum) {
1032 XmlTypeMapping map = GetTypeMapping (typeData);
1033 EnumMap emap = (EnumMap) map.ObjectMap;
1034 string res = emap.GetEnumName (map.TypeFullName, value);
1035 if (res == null) throw new InvalidOperationException ("'" + value + "' is not a valid enumeration value");
1038 return XmlCustomFormatter.FromXmlString (typeData, value);
1041 void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)
1043 XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();
1044 multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;
1045 if (choices.Count == 0) return;
1047 if (choice.MaxOccurs > 1) multiValue = true;
1049 XmlTypeMapMemberElement member;
1052 member = new XmlTypeMapMemberFlatList ();
1053 member.Name = classIds.AddUnique ("Items", member);
1054 ListMap listMap = new ListMap ();
1055 listMap.ItemInfo = choices;
1056 ((XmlTypeMapMemberFlatList)member).ListMap = listMap;
1060 member = new XmlTypeMapMemberElement ();
1061 member.Name = classIds.AddUnique ("Item", member);
1064 // If all choices have the same type, use that type for the member.
1065 // If not use System.Object.
1066 // If there are at least two choices with the same type, use a choice
1067 // identifier attribute
1069 TypeData typeData = null;
1070 bool twoEqual = false;
1071 bool allEqual = true;
1072 Hashtable types = new Hashtable ();
1074 for (int n = choices.Count - 1; n >= 0; n--)
1076 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) choices [n];
1078 // In some complex schemas, we may end up with several options
1079 // with the same name. It is better to ignore the extra options
1080 // than to crash. It's the best we can do, and btw it works
1081 // better than in MS.NET.
1083 if (cmap.GetElement (einfo.ElementName, einfo.Namespace, einfo.ExplicitOrder) != null ||
1084 choices.IndexOfElement (einfo.ElementName, einfo.Namespace) != n)
1086 choices.RemoveAt (n);
1090 if (types.ContainsKey (einfo.TypeData)) twoEqual = true;
1091 else types.Add (einfo.TypeData, einfo);
1093 TypeData choiceType = einfo.TypeData;
1094 if (choiceType.SchemaType == SchemaTypes.Class)
1096 // When comparing class types, use the most generic class in the
1097 // inheritance hierarchy
1099 XmlTypeMapping choiceMap = GetTypeMapping (choiceType);
1100 BuildPendingMap (choiceMap);
1101 while (choiceMap.BaseMap != null) {
1102 choiceMap = choiceMap.BaseMap;
1103 BuildPendingMap (choiceMap);
1104 choiceType = choiceMap.TypeData;
1108 if (typeData == null) typeData = choiceType;
1109 else if (typeData != choiceType) allEqual = false;
1113 typeData = TypeTranslator.GetTypeData (typeof(object));
1117 // Create the choice member
1118 XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();
1119 choiceMember.Ignore = true;
1120 choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);
1121 member.ChoiceMember = choiceMember.Name;
1123 // Create the choice enum
1124 XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);
1125 enumMap.IncludeInSchema = false;
1127 CodeIdentifiers codeIdents = new CodeIdentifiers ();
1128 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];
1129 for (int n=0; n<choices.Count; n++)
1131 XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];
1132 bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace);
1133 string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName;
1134 string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);
1135 members [n] = new EnumMap.EnumMapMember (xmlName, enumName);
1137 enumMap.ObjectMap = new EnumMap (members, false);
1139 choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;
1140 choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false, XmlSchemaForm.None, -1));
1141 cmap.AddMember (choiceMember);
1144 if (typeData == null)
1148 typeData = typeData.ListTypeData;
1150 member.ElementInfo = choices;
1151 member.Documentation = GetDocumentation (choice);
1152 member.TypeData = typeData;
1153 cmap.AddMember (member);
1156 bool ImportChoices (XmlQualifiedName typeQName, XmlTypeMapMember member, XmlTypeMapElementInfoList choices, XmlSchemaObjectCollection items)
1158 bool multiValue = false;
1159 foreach (XmlSchemaObject titem in items)
1161 XmlSchemaObject item = titem;
1162 if (item is XmlSchemaGroupRef)
1163 item = GetRefGroupParticle ((XmlSchemaGroupRef)item);
1165 if (item is XmlSchemaElement)
1168 XmlSchemaElement elem = (XmlSchemaElement) item;
1169 XmlTypeMapping emap;
1170 TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
1171 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
1172 choices.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap, -1));
1173 if (elem.MaxOccurs > 1) multiValue = true;
1175 else if (item is XmlSchemaAny)
1177 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));
1178 einfo.IsUnnamedAnyElement = true;
1179 choices.Add (einfo);
1181 else if (item is XmlSchemaChoice) {
1182 multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaChoice)item).Items) || multiValue;
1184 else if (item is XmlSchemaSequence) {
1185 multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaSequence)item).Items) || multiValue;
1191 void ImportSimpleContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaSimpleContent content, CodeIdentifiers classIds, bool isMixed)
1193 XmlSchemaSimpleContentExtension ext = content.Content as XmlSchemaSimpleContentExtension;
1194 ClassMap cmap = (ClassMap)map.ObjectMap;
1195 XmlQualifiedName qname = GetContentBaseType (content.Content);
1196 TypeData simpleType = null;
1198 if (!IsPrimitiveTypeNamespace (qname.Namespace))
1200 // Add base map members to this map
1202 XmlTypeMapping baseMap = ImportType (qname, null, true);
1203 BuildPendingMap (baseMap);
1205 if (baseMap.IsSimpleType) {
1206 simpleType = baseMap.TypeData;
1208 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
1210 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
1211 cmap.AddMember (member);
1213 map.BaseMap = baseMap;
1214 baseMap.DerivedTypes.Add (map);
1218 simpleType = FindBuiltInType (qname);
1220 if (simpleType != null) {
1221 XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
1222 member.Name = classIds.AddUnique("Value", member);
1223 member.TypeData = simpleType;
1224 member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData));
1225 member.IsXmlTextCollector = true;
1226 cmap.AddMember (member);
1230 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
1233 TypeData FindBuiltInType (XmlQualifiedName qname)
1235 XmlSchemaComplexType ct = (XmlSchemaComplexType) schemas.Find (qname, typeof(XmlSchemaComplexType));
1238 XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;
1239 if (sc == null) throw new InvalidOperationException ("Invalid schema");
1240 return FindBuiltInType (GetContentBaseType (sc.Content));
1243 XmlSchemaSimpleType st = (XmlSchemaSimpleType) schemas.Find (qname, typeof(XmlSchemaSimpleType));
1245 return FindBuiltInType (qname, st);
1247 if (IsPrimitiveTypeNamespace (qname.Namespace))
1248 return TypeTranslator.GetPrimitiveTypeData (qname.Name);
1250 throw new InvalidOperationException ("Definition of type '" + qname + "' not found");
1253 TypeData FindBuiltInType (XmlQualifiedName qname, XmlSchemaSimpleType st)
1255 if (CanBeEnum (st) && qname != null)
1256 return ImportType (qname, null, true).TypeData;
1258 if (st.Content is XmlSchemaSimpleTypeRestriction) {
1259 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction) st.Content;
1260 XmlQualifiedName bn = GetContentBaseType (rest);
1261 if (bn == XmlQualifiedName.Empty && rest.BaseType != null)
1262 return FindBuiltInType (qname, rest.BaseType);
1264 return FindBuiltInType (bn);
1266 else if (st.Content is XmlSchemaSimpleTypeList) {
1267 return FindBuiltInType (GetContentBaseType (st.Content)).ListTypeData;
1269 else if (st.Content is XmlSchemaSimpleTypeUnion) {
1270 // MS.NET always import simple unions as string
1271 return FindBuiltInType (new XmlQualifiedName ("string", XmlSchema.Namespace));
1277 XmlQualifiedName GetContentBaseType (XmlSchemaObject ob)
1279 if (ob is XmlSchemaSimpleContentExtension)
1280 return ((XmlSchemaSimpleContentExtension)ob).BaseTypeName;
1281 else if (ob is XmlSchemaSimpleContentRestriction)
1282 return ((XmlSchemaSimpleContentRestriction)ob).BaseTypeName;
1283 else if (ob is XmlSchemaSimpleTypeRestriction)
1284 return ((XmlSchemaSimpleTypeRestriction)ob).BaseTypeName;
1285 else if (ob is XmlSchemaSimpleTypeList)
1286 return ((XmlSchemaSimpleTypeList)ob).ItemTypeName;
1291 void ImportComplexContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaComplexContent content, CodeIdentifiers classIds, bool isMixed)
1293 ClassMap cmap = (ClassMap)map.ObjectMap;
1294 XmlQualifiedName qname;
1296 XmlSchemaComplexContentExtension ext = content.Content as XmlSchemaComplexContentExtension;
1297 if (ext != null) qname = ext.BaseTypeName;
1298 else qname = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;
1300 if (qname == typeQName)
1301 throw new InvalidOperationException ("Cannot import schema for type '" + typeQName.Name + "' from namespace '" + typeQName.Namespace + "'. Redefine not supported");
1303 // Add base map members to this map
1305 XmlTypeMapping baseMap = ImportClass (qname);
1306 BuildPendingMap (baseMap);
1307 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
1309 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
1310 cmap.AddMember (member);
1312 if (baseClassMap.XmlTextCollector != null) isMixed = false;
1313 else if (content.IsMixed) isMixed = true;
1315 map.BaseMap = baseMap;
1316 baseMap.DerivedTypes.Add (map);
1319 // Add the members of this map
1320 ImportParticleComplexContent (typeQName, cmap, ext.Particle, classIds, isMixed);
1321 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
1324 if (isMixed) ImportParticleComplexContent (typeQName, cmap, null, classIds, true);
1328 void ImportExtensionTypes (XmlQualifiedName qname)
1330 foreach (XmlSchema schema in schemas) {
1331 foreach (XmlSchemaObject sob in schema.Items)
1333 XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
1334 if (sct != null && sct.ContentModel is XmlSchemaComplexContent) {
1335 XmlQualifiedName exqname;
1336 XmlSchemaComplexContentExtension ext = sct.ContentModel.Content as XmlSchemaComplexContentExtension;
1337 if (ext != null) exqname = ext.BaseTypeName;
1338 else exqname = ((XmlSchemaComplexContentRestriction)sct.ContentModel.Content).BaseTypeName;
1339 if (exqname == qname)
1340 ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
1346 XmlTypeMapping ImportClassSimpleType (XmlQualifiedName typeQName, XmlSchemaSimpleType stype, XmlQualifiedName root)
1348 if (CanBeEnum (stype))
1350 // Create an enum map
1352 CodeIdentifiers codeIdents = new CodeIdentifiers ();
1353 XmlTypeMapping enumMap = CreateTypeMapping (typeQName, SchemaTypes.Enum, root);
1354 enumMap.Documentation = GetDocumentation (stype);
1356 bool isFlags = false;
1357 if (stype.Content is XmlSchemaSimpleTypeList) {
1358 stype = ((XmlSchemaSimpleTypeList)stype.Content).ItemType;
1361 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;
1363 codeIdents.AddReserved (enumMap.TypeData.TypeName);
1365 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [rest.Facets.Count];
1366 for (int n=0; n<rest.Facets.Count; n++)
1368 XmlSchemaEnumerationFacet enu = (XmlSchemaEnumerationFacet) rest.Facets[n];
1369 string enumName = codeIdents.AddUnique(CodeIdentifier.MakeValid (enu.Value), enu);
1370 members [n] = new EnumMap.EnumMapMember (enu.Value, enumName);
1371 members [n].Documentation = GetDocumentation (enu);
1373 enumMap.ObjectMap = new EnumMap (members, isFlags);
1374 enumMap.IsSimpleType = true;
1378 if (stype.Content is XmlSchemaSimpleTypeList)
1380 XmlSchemaSimpleTypeList slist = (XmlSchemaSimpleTypeList)stype.Content;
1381 TypeData arrayTypeData = FindBuiltInType (slist.ItemTypeName, stype);
1383 ListMap listMap = new ListMap ();
1385 listMap.ItemInfo = new XmlTypeMapElementInfoList ();
1386 listMap.ItemInfo.Add (CreateElementInfo (typeQName.Namespace, null, "Item", arrayTypeData.ListItemTypeData, false, XmlSchemaForm.None, -1));
1388 XmlTypeMapping map = CreateArrayTypeMapping (typeQName, arrayTypeData);
1389 map.ObjectMap = listMap;
1390 map.IsSimpleType = true;
1394 // It is an extension of a primitive or known type
1396 TypeData typeData = FindBuiltInType (typeQName, stype);
1397 XmlTypeMapping rmap = GetTypeMapping (typeData);
1399 // The resulting map must be a simple type. It needs to be explicitely set for arrays
1400 rmap.IsSimpleType = true;
1404 bool CanBeEnum (XmlSchemaSimpleType stype)
1406 if (stype.Content is XmlSchemaSimpleTypeRestriction)
1408 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;
1409 if (rest.Facets.Count == 0) return false;
1410 foreach (object ob in rest.Facets)
1411 if (!(ob is XmlSchemaEnumerationFacet)) return false;
1414 else if (stype.Content is XmlSchemaSimpleTypeList)
1416 XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList) stype.Content;
1417 return (list.ItemType != null && CanBeEnum (list.ItemType));
1422 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaComplexType stype)
1426 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
1427 if (content == null) return false;
1428 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
1429 if (rest == null) return false;
1430 return rest.BaseTypeName == arrayType;
1434 if (stype.Attributes.Count > 0 || stype.AnyAttribute != null) return false;
1435 else return !stype.IsMixed && CanBeArray (typeQName, stype.Particle, false);
1439 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaParticle particle, bool multiValue)
1441 // To be an array, there can't be a direct child of type typeQName
1443 if (particle == null) return false;
1445 multiValue = multiValue || particle.MaxOccurs > 1;
1447 if (particle is XmlSchemaGroupRef)
1448 return CanBeArray (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), multiValue);
1450 if (particle is XmlSchemaElement)
1452 XmlSchemaElement elem = (XmlSchemaElement)particle;
1453 if (!elem.RefName.IsEmpty)
1454 return CanBeArray (typeQName, FindRefElement (elem), multiValue);
1456 return multiValue && !typeQName.Equals (((XmlSchemaElement)particle).SchemaTypeName);
1459 if (particle is XmlSchemaAny)
1462 if (particle is XmlSchemaSequence)
1464 XmlSchemaSequence seq = particle as XmlSchemaSequence;
1465 if (seq.Items.Count != 1) return false;
1466 return CanBeArray (typeQName, (XmlSchemaParticle)seq.Items[0], multiValue);
1469 if (particle is XmlSchemaChoice)
1471 // Can be array if all choices have different types
1472 ArrayList types = new ArrayList ();
1473 if(!CheckChoiceType (typeQName, particle, types, ref multiValue)) return false;
1480 bool CheckChoiceType (XmlQualifiedName typeQName, XmlSchemaParticle particle, ArrayList types, ref bool multiValue)
1482 XmlQualifiedName type = null;
1484 multiValue = multiValue || particle.MaxOccurs > 1;
1486 if (particle is XmlSchemaGroupRef)
1487 return CheckChoiceType (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), types, ref multiValue);
1489 if (particle is XmlSchemaElement) {
1491 XmlSchemaElement elem = (XmlSchemaElement)particle;
1492 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
1493 if (refElem.SchemaType != null) return true;
1494 type = refElem.SchemaTypeName;
1496 else if (particle is XmlSchemaAny) {
1499 else if (particle is XmlSchemaSequence)
1501 XmlSchemaSequence seq = particle as XmlSchemaSequence;
1502 foreach (XmlSchemaParticle par in seq.Items)
1503 if (!CheckChoiceType (typeQName, par, types, ref multiValue)) return false;
1506 else if (particle is XmlSchemaChoice)
1508 foreach (XmlSchemaParticle choice in ((XmlSchemaChoice)particle).Items)
1509 if (!CheckChoiceType (typeQName, choice, types, ref multiValue)) return false;
1513 if (typeQName.Equals (type)) return false;
1515 // For primitive types, compare using CLR types, since several
1516 // xml types can be mapped to a single CLR type
1519 if (IsPrimitiveTypeNamespace (type.Namespace))
1520 t = TypeTranslator.GetPrimitiveTypeData (type.Name).FullTypeName + ":" + type.Namespace;
1523 t = type.Name + ":" + type.Namespace;
1525 if (types.Contains (t)) return false;
1530 bool CanBeAnyElement (XmlSchemaComplexType stype)
1532 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
1533 return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);
1536 Type GetAnyElementType (XmlSchemaComplexType stype)
1538 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
1540 if ((seq == null) || (seq.Items.Count != 1) || !(seq.Items[0] is XmlSchemaAny))
1544 return typeof(object);
1546 XmlSchemaAny any = seq.Items[0] as XmlSchemaAny;
1547 if (any.MaxOccurs == 1)
1550 return typeof(XmlNode);
1552 return typeof(XmlElement);
1557 return typeof(XmlNode[]);
1559 return typeof(XmlElement[]);
1563 bool CanBeIXmlSerializable (XmlSchemaComplexType stype)
1565 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
1566 if (seq == null) return false;
1567 if (seq.Items.Count != 2) return false;
1568 XmlSchemaElement elem = seq.Items[0] as XmlSchemaElement;
1569 if (elem == null) return false;
1570 if (elem.RefName != new XmlQualifiedName ("schema",XmlSchema.Namespace)) return false;
1571 return (seq.Items[1] is XmlSchemaAny);
1574 XmlTypeMapping ImportXmlSerializableMapping (string ns)
1576 XmlQualifiedName qname = new XmlQualifiedName ("System.Data.DataSet",ns);
1577 XmlTypeMapping map = GetRegisteredTypeMapping (qname);
1578 if (map != null) return map;
1580 TypeData typeData = new TypeData ("System.Data.DataSet", "System.Data.DataSet", "System.Data.DataSet", SchemaTypes.XmlSerializable, null);
1581 map = new XmlTypeMapping ("System.Data.DataSet", "", typeData, "System.Data.DataSet", ns);
1582 map.IncludeInSchema = true;
1583 RegisterTypeMapping (qname, typeData, map);
1587 XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form, int order)
1589 if (typeData.IsComplexType)
1590 return CreateElementInfo (ns, member, name, typeData, isNillable, form, GetTypeMapping (typeData), order);
1592 return CreateElementInfo (ns, member, name, typeData, isNillable, form, null, order);
1595 XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form, XmlTypeMapping emap, int order)
1597 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
1598 einfo.ElementName = name;
1599 einfo.Namespace = ns;
1600 einfo.IsNullable = isNillable;
1601 einfo.Form = GetForm (form, ns, true);
1602 if (typeData.IsComplexType)
1603 einfo.MappedType = emap;
1604 einfo.ExplicitOrder = order;
1608 XmlSchemaForm GetForm (XmlSchemaForm form, string ns, bool forElement)
1610 // Returns the schema form for an element or attribute, taking
1611 // into account the schema defaults. If the form has not been explicitly
1612 // set and there is no default, use Unqualified as default.
1614 if (form != XmlSchemaForm.None)
1616 XmlSchema s = schemas [ns];
1618 return XmlSchemaForm.Unqualified;
1619 XmlSchemaForm schemaForm = forElement ? s.ElementFormDefault : s.AttributeFormDefault;
1620 if (schemaForm != XmlSchemaForm.None)
1623 return XmlSchemaForm.Unqualified;
1626 XmlTypeMapElementInfo CreateTextElementInfo (string ns, XmlTypeMapMember member, TypeData typeData)
1628 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
1629 einfo.IsTextElement = true;
1630 einfo.WrappedElement = false;
1631 if (typeData.IsComplexType)
1632 einfo.MappedType = GetTypeMapping (typeData);
1636 XmlTypeMapping CreateTypeMapping (XmlQualifiedName typeQName, SchemaTypes schemaType, XmlQualifiedName root)
1638 string typeName = CodeIdentifier.MakeValid (typeQName.Name);
1639 typeName = typeIdentifiers.AddUnique (typeName, null);
1641 TypeData typeData = new TypeData (typeName, typeName, typeName, schemaType, null);
1646 rootElem = root.Name;
1647 rootNs = root.Namespace;
1650 rootElem = typeQName.Name;
1654 XmlTypeMapping map = new XmlTypeMapping (rootElem, rootNs, typeData, typeQName.Name, typeQName.Namespace);
1655 map.IncludeInSchema = true;
1656 RegisterTypeMapping (typeQName, typeData, map);
1661 XmlTypeMapping CreateArrayTypeMapping (XmlQualifiedName typeQName, TypeData arrayTypeData)
1664 if (encodedFormat) map = new XmlTypeMapping ("Array", XmlSerializer.EncodingNamespace, arrayTypeData, "Array", XmlSerializer.EncodingNamespace);
1665 else map = new XmlTypeMapping (arrayTypeData.XmlType, typeQName.Namespace, arrayTypeData, arrayTypeData.XmlType, typeQName.Namespace);
1667 map.IncludeInSchema = true;
1668 RegisterTypeMapping (typeQName, arrayTypeData, map);
1673 XmlSchemaElement GetRefElement (XmlQualifiedName typeQName, XmlSchemaElement elem, out string ns)
1676 if (!elem.RefName.IsEmpty)
1678 ns = elem.RefName.Namespace;
1679 return FindRefElement (elem);
1683 ns = typeQName.Namespace;
1688 XmlSchemaAttribute GetRefAttribute (XmlQualifiedName typeQName, XmlSchemaAttribute attr, out string ns)
1690 if (!attr.RefName.IsEmpty)
1692 ns = attr.RefName.Namespace;
1693 XmlSchemaAttribute at = FindRefAttribute (attr.RefName);
1694 if (at == null) throw new InvalidOperationException ("The attribute " + attr.RefName + " is missing");
1699 ns = attr.ParentIsSchema ? typeQName.Namespace : String.Empty;
1704 TypeData GetElementTypeData (XmlQualifiedName typeQName, XmlSchemaElement elem, XmlQualifiedName root, out XmlTypeMapping map)
1706 bool sharedAnnType = false;
1709 if (!elem.RefName.IsEmpty) {
1710 XmlSchemaElement refElem = FindRefElement (elem);
1711 if (refElem == null) throw new InvalidOperationException ("Global element not found: " + elem.RefName);
1712 root = elem.RefName;
1714 sharedAnnType = true;
1718 if (!elem.SchemaTypeName.IsEmpty) {
1719 td = GetTypeData (elem.SchemaTypeName, root, elem.IsNillable);
1720 map = GetRegisteredTypeMapping (td);
1722 else if (elem.SchemaType == null)
1723 td = TypeTranslator.GetTypeData (typeof(object));
1725 td = GetTypeData (elem.SchemaType, typeQName, elem.Name, sharedAnnType, root);
1727 if (map == null && td.IsComplexType)
1728 map = GetTypeMapping (td);
1733 TypeData GetAttributeTypeData (XmlQualifiedName typeQName, XmlSchemaAttribute attr)
1735 bool sharedAnnType = false;
1737 if (!attr.RefName.IsEmpty) {
1738 XmlSchemaAttribute refAtt = FindRefAttribute (attr.RefName);
1739 if (refAtt == null) throw new InvalidOperationException ("Global attribute not found: " + attr.RefName);
1741 sharedAnnType = true;
1744 if (!attr.SchemaTypeName.IsEmpty) return GetTypeData (attr.SchemaTypeName, null, false);
1745 if (attr.SchemaType == null) return TypeTranslator.GetTypeData (typeof(string));
1746 else return GetTypeData (attr.SchemaType, typeQName, attr.Name, sharedAnnType, null);
1749 TypeData GetTypeData (XmlQualifiedName typeQName, XmlQualifiedName root, bool isNullable)
1751 if (IsPrimitiveTypeNamespace (typeQName.Namespace)) {
1752 XmlTypeMapping map = ImportType (typeQName, root, false);
1753 if (map != null) return map.TypeData;
1754 else return TypeTranslator.GetPrimitiveTypeData (typeQName.Name, isNullable);
1757 if (encodedFormat && typeQName.Namespace == "")
1758 return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);
1760 return ImportType (typeQName, root, true).TypeData;
1763 TypeData GetTypeData (XmlSchemaType stype, XmlQualifiedName typeQNname, string propertyName, bool sharedAnnType, XmlQualifiedName root)
1769 // Anonymous types defined in root elements or attributes can be shared among all elements that
1770 // reference this root element or attribute
1771 TypeData std = sharedAnonymousTypes [stype] as TypeData;
1772 if (std != null) return std;
1773 baseName = propertyName;
1776 baseName = typeQNname.Name + typeIdentifiers.MakeRightCase (propertyName);
1778 baseName = elemIdentifiers.AddUnique (baseName, stype);
1780 XmlQualifiedName newName;
1781 newName = new XmlQualifiedName (baseName, typeQNname.Namespace);
1783 XmlTypeMapping map = ImportType (newName, stype, root);
1784 if (sharedAnnType) sharedAnonymousTypes [stype] = map.TypeData;
1786 return map.TypeData;
1789 XmlTypeMapping GetTypeMapping (TypeData typeData)
1791 if (typeData.Type == typeof(object) && !anyTypeImported)
1792 ImportAllObjectTypes ();
1794 XmlTypeMapping map = GetRegisteredTypeMapping (typeData);
1795 if (map != null) return map;
1797 if (typeData.IsListType)
1799 // Create an array map for the type
1801 XmlTypeMapping itemMap = GetTypeMapping (typeData.ListItemTypeData);
1803 map = new XmlTypeMapping (typeData.XmlType, itemMap.Namespace, typeData, typeData.XmlType, itemMap.Namespace);
1804 map.IncludeInSchema = true;
1806 ListMap listMap = new ListMap ();
1807 listMap.ItemInfo = new XmlTypeMapElementInfoList();
1808 listMap.ItemInfo.Add (CreateElementInfo (itemMap.Namespace, null, typeData.ListItemTypeData.XmlType, typeData.ListItemTypeData, false, XmlSchemaForm.None, -1));
1809 map.ObjectMap = listMap;
1811 RegisterTypeMapping (new XmlQualifiedName(map.ElementName, map.Namespace), typeData, map);
1814 else if (typeData.SchemaType == SchemaTypes.Primitive || typeData.Type == typeof(object) || typeof(XmlNode).IsAssignableFrom(typeData.Type))
1816 return CreateSystemMap (typeData);
1819 throw new InvalidOperationException ("Map for type " + typeData.TypeName + " not found");
1822 void AddObjectDerivedMap (XmlTypeMapping map)
1824 TypeData typeData = TypeTranslator.GetTypeData (typeof(object));
1825 XmlTypeMapping omap = GetRegisteredTypeMapping (typeData);
1827 omap = CreateSystemMap (typeData);
1828 omap.DerivedTypes.Add (map);
1831 XmlTypeMapping CreateSystemMap (TypeData typeData)
1833 XmlTypeMapping map = new XmlTypeMapping (typeData.XmlType, XmlSchema.Namespace, typeData, typeData.XmlType, XmlSchema.Namespace);
1834 map.IncludeInSchema = false;
1835 map.ObjectMap = new ClassMap ();
1836 dataMappedTypes [typeData] = map;
1840 void ImportAllObjectTypes ()
1842 // All complex types are subtypes of anyType, so all of them
1843 // must also be imported
1845 anyTypeImported = true;
1846 foreach (XmlSchema schema in schemas) {
1847 foreach (XmlSchemaObject sob in schema.Items)
1849 XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
1851 ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
1856 XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName, Type baseType)
1858 // Primitive types with a forced base class are stored in a different table.
1859 // In this way it is possible to have two maps for primitive types: one with
1860 // the forced base class (returned by ImportDerivedTypeMapping) and one
1861 // with the regular primitive map.
1863 if (IsPrimitiveTypeNamespace (typeQName.Namespace))
1864 return (XmlTypeMapping) primitiveDerivedMappedTypes [typeQName];
1866 return (XmlTypeMapping) mappedTypes [typeQName];
1869 XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName)
1871 return (XmlTypeMapping) mappedTypes [typeQName];
1874 XmlTypeMapping GetRegisteredTypeMapping (TypeData typeData)
1876 return (XmlTypeMapping) dataMappedTypes [typeData];
1879 void RegisterTypeMapping (XmlQualifiedName qname, TypeData typeData, XmlTypeMapping map)
1881 // Primitive types with a forced base class are stored in a different table.
1882 // In this way it is possible to have two maps for primitive types: one with
1883 // the forced base class (returned by ImportDerivedTypeMapping) and one
1884 // with the regular primitive map.
1886 dataMappedTypes [typeData] = map;
1887 if (IsPrimitiveTypeNamespace (qname.Namespace) && !map.IsSimpleType)
1888 primitiveDerivedMappedTypes [qname] = map;
1890 mappedTypes [qname] = map;
1893 XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)
1895 XmlSchemaGroup grp = (XmlSchemaGroup) schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));
1896 return grp.Particle;
1899 XmlSchemaElement FindRefElement (XmlSchemaElement elem)
1901 XmlSchemaElement refelem = (XmlSchemaElement) schemas.Find (elem.RefName, typeof(XmlSchemaElement));
1902 if (refelem != null) return refelem;
1904 if (IsPrimitiveTypeNamespace (elem.RefName.Namespace))
1906 if (anyElement != null) return anyElement;
1907 anyElement = new XmlSchemaElement ();
1908 anyElement.Name = "any";
1909 anyElement.SchemaTypeName = anyType;
1915 XmlSchemaAttribute FindRefAttribute (XmlQualifiedName refName)
1917 if (refName.Namespace == XmlNamespace)
1919 XmlSchemaAttribute at = new XmlSchemaAttribute ();
1920 at.Name = refName.Name;
1921 at.SchemaTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
1924 return (XmlSchemaAttribute) schemas.Find (refName, typeof(XmlSchemaAttribute));
1927 XmlSchemaAttributeGroup FindRefAttributeGroup (XmlQualifiedName refName)
1929 XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (refName, typeof(XmlSchemaAttributeGroup));
1930 foreach (XmlSchemaObject at in grp.Attributes)
1932 if (at is XmlSchemaAttributeGroupRef && ((XmlSchemaAttributeGroupRef)at).RefName == refName)
1933 throw new InvalidOperationException ("Cannot import attribute group '" + refName.Name + "' from namespace '" + refName.Namespace + "'. Redefine not supported");
1939 XmlTypeMapping ReflectType (Type type)
1941 TypeData typeData = TypeTranslator.GetTypeData (type);
1942 return ReflectType (typeData, (string) null);
1945 XmlTypeMapping ReflectType (TypeData typeData, string ns)
1949 if (auxXmlRefImporter == null) auxXmlRefImporter = new XmlReflectionImporter ();
1950 return auxXmlRefImporter.ImportTypeMapping (typeData, ns);
1954 if (auxSoapRefImporter == null) auxSoapRefImporter = new SoapReflectionImporter ();
1955 return auxSoapRefImporter.ImportTypeMapping (typeData, ns);
1960 string GetDocumentation (XmlSchemaAnnotated elem)
1963 XmlSchemaAnnotation anot = elem.Annotation;
1964 if (anot == null || anot.Items == null) return null;
1966 foreach (object ob in anot.Items)
1968 XmlSchemaDocumentation doc = ob as XmlSchemaDocumentation;
1969 if (doc != null && doc.Markup != null && doc.Markup.Length > 0) {
1970 if (res != string.Empty) res += "\n";
1971 foreach (XmlNode node in doc.Markup)
1978 bool IsPrimitiveTypeNamespace (string ns)
1980 return (ns == XmlSchema.Namespace) || (encodedFormat && ns == XmlSerializer.EncodingNamespace);
1983 #endregion // Methods