2 // System.Xml.Serialization.XmlSchemaImporter
\r
5 // Tim Coleman (tim@timcoleman.com)
\r
6 // Lluis Sanchez Gual (lluis@ximian.com)
\r
8 // Copyright (C) Tim Coleman, 2002
\r
12 // Permission is hereby granted, free of charge, to any person obtaining
\r
13 // a copy of this software and associated documentation files (the
\r
14 // "Software"), to deal in the Software without restriction, including
\r
15 // without limitation the rights to use, copy, modify, merge, publish,
\r
16 // distribute, sublicense, and/or sell copies of the Software, and to
\r
17 // permit persons to whom the Software is furnished to do so, subject to
\r
18 // the following conditions:
\r
20 // The above copyright notice and this permission notice shall be
\r
21 // included in all copies or substantial portions of the Software.
\r
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
34 using System.CodeDom.Compiler;
\r
36 using System.Xml.Schema;
\r
37 using System.Collections;
\r
38 #if NET_2_0 && CONFIGURATION_DEP
\r
39 using System.Configuration;
\r
40 using System.Xml.Serialization.Configuration;
\r
43 namespace System.Xml.Serialization
\r
45 public class XmlSchemaImporter
\r
53 CodeIdentifiers typeIdentifiers;
\r
54 CodeIdentifiers elemIdentifiers = new CodeIdentifiers ();
\r
55 Hashtable mappedTypes = new Hashtable ();
\r
56 Hashtable dataMappedTypes = new Hashtable ();
\r
57 Queue pendingMaps = new Queue ();
\r
58 Hashtable sharedAnonymousTypes = new Hashtable ();
\r
59 bool encodedFormat = false;
\r
60 XmlReflectionImporter auxXmlRefImporter;
\r
61 SoapReflectionImporter auxSoapRefImporter;
\r
62 bool anyTypeImported;
\r
65 CodeGenerationOptions options;
\r
68 static readonly XmlQualifiedName anyType = new XmlQualifiedName ("anyType",XmlSchema.Namespace);
\r
69 static readonly XmlQualifiedName arrayType = new XmlQualifiedName ("Array",XmlSerializer.EncodingNamespace);
\r
70 static readonly XmlQualifiedName arrayTypeRefName = new XmlQualifiedName ("arrayType",XmlSerializer.EncodingNamespace);
\r
72 const string XmlNamespace = "http://www.w3.org/XML/1998/namespace";
\r
74 XmlSchemaElement anyElement = null;
\r
78 public XmlTypeMapping Map;
\r
79 public XmlSchemaComplexType SchemaType;
\r
80 public XmlQualifiedName TypeName;
\r
85 #region Constructors
\r
87 public XmlSchemaImporter (XmlSchemas schemas)
\r
89 this.schemas = schemas;
\r
90 typeIdentifiers = new CodeIdentifiers ();
\r
92 InitializeExtensions ();
\r
95 public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers)
\r
98 this.typeIdentifiers = typeIdentifiers;
\r
104 public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, CodeDomProvider codeProvider, ImportContext context)
\r
106 this.schemas = schemas;
\r
107 this.options = options;
\r
108 if (context != null) {
\r
109 typeIdentifiers = context.TypeIdentifiers;
\r
110 InitSharedData (context);
\r
113 typeIdentifiers = new CodeIdentifiers ();
\r
115 InitializeExtensions ();
\r
119 public XmlSchemaImporter (XmlSchemas schemas, CodeGenerationOptions options, ImportContext context)
\r
121 this.schemas = schemas;
\r
122 this.options = options;
\r
123 if (context != null) {
\r
124 typeIdentifiers = context.TypeIdentifiers;
\r
125 InitSharedData (context);
\r
128 typeIdentifiers = new CodeIdentifiers ();
\r
130 InitializeExtensions ();
\r
134 public XmlSchemaImporter (XmlSchemas schemas, CodeIdentifiers typeIdentifiers, CodeGenerationOptions options)
\r
136 this.typeIdentifiers = typeIdentifiers;
\r
137 this.schemas = schemas;
\r
138 this.options = options;
\r
140 InitializeExtensions ();
\r
143 void InitSharedData (ImportContext context)
\r
145 if (context.ShareTypes) {
\r
146 mappedTypes = context.MappedTypes;
\r
147 dataMappedTypes = context.DataMappedTypes;
\r
148 sharedAnonymousTypes = context.SharedAnonymousTypes;
\r
153 internal bool UseEncodedFormat
\r
155 get { return encodedFormat; }
\r
156 set { encodedFormat = value; }
\r
159 #endregion // Constructors
\r
163 void InitializeExtensions ()
\r
165 #if NET_2_0 && CONFIGURATION_DEP
\r
166 SerializationSectionGroup root = ConfigurationManager.GetSection ("system.xml.serialization") as SerializationSectionGroup;
\r
170 foreach (SchemaImporterExtensionElement element in
\r
171 root.SchemaImporterExtensions.SchemaImporterExtensions)
\r
172 Extensions.Add (element.Name, element.Type);
\r
176 public XmlMembersMapping ImportAnyType (XmlQualifiedName typeName, string elementName)
\r
178 if (typeName == XmlQualifiedName.Empty)
\r
180 XmlTypeMapMemberAnyElement mapMem = new XmlTypeMapMemberAnyElement ();
\r
181 mapMem.Name = typeName.Name;
\r
182 mapMem.TypeData = TypeTranslator.GetTypeData(typeof(XmlNode));
\r
183 mapMem.ElementInfo.Add (CreateElementInfo (typeName.Namespace, mapMem, typeName.Name, mapMem.TypeData, true, XmlSchemaForm.None));
\r
185 XmlMemberMapping[] mm = new XmlMemberMapping [1];
\r
186 mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
\r
187 return new XmlMembersMapping (mm);
\r
191 XmlSchemaComplexType stype = (XmlSchemaComplexType) schemas.Find (typeName, typeof (XmlSchemaComplexType));
\r
192 if (stype == null)
\r
193 throw new InvalidOperationException ("Referenced type '" + typeName + "' not found");
\r
195 if (!CanBeAnyElement (stype))
\r
196 throw new InvalidOperationException ("The type '" + typeName + "' is not valid for a collection of any elements");
\r
198 ClassMap cmap = new ClassMap ();
\r
199 CodeIdentifiers classIds = new CodeIdentifiers ();
\r
200 bool isMixed = stype.IsMixed;
\r
201 ImportSequenceContent (typeName, cmap, ((XmlSchemaSequence) stype.Particle).Items, classIds, false, ref isMixed);
\r
202 XmlTypeMapMemberAnyElement mapMem = (XmlTypeMapMemberAnyElement) cmap.AllMembers[0];
\r
203 mapMem.Name = typeName.Name;
\r
205 XmlMemberMapping[] mm = new XmlMemberMapping [1];
\r
206 mm[0] = new XmlMemberMapping (typeName.Name, typeName.Namespace, mapMem, encodedFormat);
\r
207 return new XmlMembersMapping (mm);
\r
211 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType)
\r
213 return ImportDerivedTypeMapping (name, baseType, true);
\r
216 public XmlTypeMapping ImportDerivedTypeMapping (XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
\r
218 XmlQualifiedName qname;
\r
219 XmlSchemaType stype;
\r
224 stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
\r
225 if (stype == null) throw new InvalidOperationException ("Schema type '" + name + "' not found or not valid");
\r
229 if (!LocateElement (name, out qname, out stype))
\r
233 XmlTypeMapping map = GetRegisteredTypeMapping (qname);
\r
236 // If the type has already been imported, make sure that the map
\r
237 // has the requested base type
\r
239 SetMapBaseType (map, baseType);
\r
240 map.UpdateRoot (name);
\r
244 map = CreateTypeMapping (qname, SchemaTypes.Class, name);
\r
245 if (stype != null) {
\r
246 map.Documentation = GetDocumentation (stype);
\r
247 RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
\r
249 ClassMap cmap = new ClassMap ();
\r
250 CodeIdentifiers classIds = new CodeIdentifiers ();
\r
251 map.ObjectMap = cmap;
\r
252 AddTextMember (qname, cmap, classIds);
\r
255 BuildPendingMaps ();
\r
256 SetMapBaseType (map, baseType);
\r
261 void SetMapBaseType (XmlTypeMapping map, Type baseType)
\r
263 // This method sets the base type for a given map.
\r
264 // If the map already inherits from this type, it does nothing.
\r
266 // Fiirst of all, check if the map already inherits from baseType
\r
268 XmlTypeMapping topMap = null;
\r
269 while (map != null)
\r
271 if (map.TypeData.Type == baseType)
\r
277 // Does not have the requested base type.
\r
278 // Then, get/create a map for that base type.
\r
280 XmlTypeMapping baseMap = ReflectType (baseType);
\r
282 // Add this map as a derived map of the base map
\r
284 topMap.BaseMap = baseMap;
\r
285 baseMap.DerivedTypes.Add (topMap);
\r
286 baseMap.DerivedTypes.AddRange (topMap.DerivedTypes);
\r
288 // Now add the base type fields to all derived maps
\r
290 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
\r
292 ClassMap cmap = (ClassMap)topMap.ObjectMap;
\r
293 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
\r
294 cmap.AddMember (member);
\r
296 foreach (XmlTypeMapping derivedMap in topMap.DerivedTypes)
\r
298 cmap = (ClassMap)derivedMap.ObjectMap;
\r
299 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
\r
300 cmap.AddMember (member);
\r
304 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName name)
\r
306 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
\r
307 if (elem == null) throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");
\r
309 XmlSchemaComplexType stype;
\r
310 if (elem.SchemaType != null)
\r
312 stype = elem.SchemaType as XmlSchemaComplexType;
\r
316 if (elem.SchemaTypeName.IsEmpty) return null;
\r
317 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
\r
318 if (type == null) {
\r
319 if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) return null;
\r
320 throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
\r
322 stype = type as XmlSchemaComplexType;
\r
325 if (stype == null)
\r
326 throw new InvalidOperationException ("Schema element '" + name + "' not found or not valid");
\r
328 XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, name);
\r
329 return new XmlMembersMapping (name.Name, name.Namespace, mapping);
\r
332 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names)
\r
334 XmlMemberMapping[] mapping = new XmlMemberMapping [names.Length];
\r
335 for (int n=0; n<names.Length; n++)
\r
337 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (names[n], typeof (XmlSchemaElement));
\r
338 if (elem == null) throw new InvalidOperationException ("Schema element '" + names[n] + "' not found");
\r
340 XmlQualifiedName typeQName = new XmlQualifiedName ("Message", names[n].Namespace);
\r
341 XmlTypeMapping tmap;
\r
342 TypeData td = GetElementTypeData (typeQName, elem, names[n], out tmap);
\r
344 mapping[n] = ImportMemberMapping (elem.Name, typeQName.Namespace, elem.IsNillable, td, tmap);
\r
346 BuildPendingMaps ();
\r
347 return new XmlMembersMapping (mapping);
\r
352 public XmlMembersMapping ImportMembersMapping (string name, string ns, SoapSchemaMember[] members)
\r
354 throw new NotImplementedException ();
\r
358 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName)
\r
360 throw new NotImplementedException ();
\r
364 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType)
\r
366 throw new NotImplementedException ();
\r
370 public XmlTypeMapping ImportSchemaType (XmlQualifiedName typeName, Type baseType, bool baseTypeCanBeIndirect)
\r
372 throw new NotImplementedException ();
\r
376 internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement)
\r
378 XmlMemberMapping[] mapping = new XmlMemberMapping [members.Length];
\r
379 for (int n=0; n<members.Length; n++)
\r
381 TypeData td = GetTypeData (members[n].MemberType, null);
\r
382 XmlTypeMapping tmap = GetTypeMapping (td);
\r
383 mapping[n] = ImportMemberMapping (members[n].MemberName, members[n].MemberType.Namespace, true, td, tmap);
\r
385 BuildPendingMaps ();
\r
386 return new XmlMembersMapping (name, ns, hasWrapperElement, false, mapping);
\r
389 internal XmlMembersMapping ImportEncodedMembersMapping (string name, string ns, SoapSchemaMember member)
\r
391 XmlSchemaComplexType stype = schemas.Find (member.MemberType, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
\r
392 if (stype == null) throw new InvalidOperationException ("Schema type '" + member.MemberType + "' not found or not valid");
\r
394 XmlMemberMapping[] mapping = ImportMembersMappingComposite (stype, member.MemberType);
\r
395 return new XmlMembersMapping (name, ns, mapping);
\r
398 XmlMemberMapping[] ImportMembersMappingComposite (XmlSchemaComplexType stype, XmlQualifiedName refer)
\r
400 if (stype.Particle == null)
\r
401 return new XmlMemberMapping [0];
\r
403 ClassMap cmap = new ClassMap ();
\r
405 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
\r
406 if (seq == null) throw new InvalidOperationException ("Schema element '" + refer + "' cannot be imported as XmlMembersMapping");
\r
408 CodeIdentifiers classIds = new CodeIdentifiers ();
\r
409 ImportParticleComplexContent (refer, cmap, seq, classIds, false);
\r
410 ImportAttributes (refer, cmap, stype.Attributes, stype.AnyAttribute, classIds);
\r
412 BuildPendingMaps ();
\r
415 XmlMemberMapping[] mapping = new XmlMemberMapping [cmap.AllMembers.Count];
\r
416 foreach (XmlTypeMapMember mapMem in cmap.AllMembers)
\r
417 mapping[n++] = new XmlMemberMapping (mapMem.Name, refer.Namespace, mapMem, encodedFormat);
\r
422 XmlMemberMapping ImportMemberMapping (string name, string ns, bool isNullable, TypeData type, XmlTypeMapping emap)
\r
424 XmlTypeMapMemberElement mapMem;
\r
426 if (type.IsListType)
\r
427 mapMem = new XmlTypeMapMemberList ();
\r
429 mapMem = new XmlTypeMapMemberElement ();
\r
431 mapMem.Name = name;
\r
432 mapMem.TypeData = type;
\r
433 mapMem.ElementInfo.Add (CreateElementInfo (ns, mapMem, name, type, isNullable, XmlSchemaForm.None, emap));
\r
434 return new XmlMemberMapping (name, ns, mapMem, encodedFormat);
\r
438 public XmlMembersMapping ImportMembersMapping (XmlQualifiedName[] names, Type baseType, bool baseTypeCanBeIndirect)
\r
440 throw new NotImplementedException ();
\r
443 public XmlTypeMapping ImportTypeMapping (XmlQualifiedName name)
\r
445 XmlQualifiedName qname;
\r
446 XmlSchemaType stype;
\r
448 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
\r
449 if (!LocateElement (elem, out qname, out stype)) return null;
\r
451 if (stype == null) {
\r
452 // Importing a primitive type
\r
453 TypeData td = TypeTranslator.GetPrimitiveTypeData (qname.Name);
\r
454 return ReflectType (td, name.Namespace);
\r
457 XmlTypeMapping map = GetRegisteredTypeMapping (qname);
\r
458 if (map != null) return map;
\r
460 map = CreateTypeMapping (qname, SchemaTypes.Class, name);
\r
461 map.Documentation = GetDocumentation (stype);
\r
462 map.IsNullable = elem.IsNillable;
\r
463 RegisterMapFixup (map, qname, (XmlSchemaComplexType)stype);
\r
465 BuildPendingMaps ();
\r
469 bool LocateElement (XmlQualifiedName name, out XmlQualifiedName qname, out XmlSchemaType stype)
\r
471 XmlSchemaElement elem = (XmlSchemaElement) schemas.Find (name, typeof (XmlSchemaElement));
\r
472 return LocateElement (elem, out qname, out stype);
\r
475 bool LocateElement (XmlSchemaElement elem, out XmlQualifiedName qname, out XmlSchemaType stype)
\r
480 if (elem == null) return false;
\r
482 // The root element must be an element with complex type
\r
484 if (elem.SchemaType != null)
\r
486 stype = elem.SchemaType;
\r
487 qname = elem.QualifiedName;
\r
491 if (elem.SchemaTypeName.IsEmpty) return false;
\r
493 object type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaComplexType));
\r
494 if (type == null) type = schemas.Find (elem.SchemaTypeName, typeof (XmlSchemaSimpleType));
\r
495 if (type == null) {
\r
496 if (IsPrimitiveTypeNamespace (elem.SchemaTypeName.Namespace)) {
\r
497 qname = elem.SchemaTypeName;
\r
500 throw new InvalidOperationException ("Schema type '" + elem.SchemaTypeName + "' not found");
\r
502 stype = (XmlSchemaType) type;
\r
503 qname = stype.QualifiedName;
\r
505 XmlSchemaType btype = stype.BaseSchemaType as XmlSchemaType;
\r
506 if (btype != null && btype.QualifiedName == elem.SchemaTypeName)
\r
507 throw new InvalidOperationException ("Cannot import schema for type '" + elem.SchemaTypeName.Name + "' from namespace '" + elem.SchemaTypeName.Namespace + "'. Redefine not supported");
\r
510 if (stype is XmlSchemaSimpleType) return false;
\r
514 XmlTypeMapping ImportType (XmlQualifiedName name, XmlQualifiedName root, bool throwOnError)
\r
516 XmlTypeMapping map = GetRegisteredTypeMapping (name);
\r
518 map.UpdateRoot (root);
\r
522 XmlSchemaType type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaComplexType));
\r
523 if (type == null) type = (XmlSchemaType) schemas.Find (name, typeof (XmlSchemaSimpleType));
\r
527 if (throwOnError) {
\r
528 if (name.Namespace == XmlSerializer.EncodingNamespace)
\r
529 throw new InvalidOperationException ("Referenced type '" + name + "' valid only for encoded SOAP.");
\r
531 throw new InvalidOperationException ("Referenced type '" + name + "' not found.");
\r
536 return ImportType (name, type, root);
\r
539 XmlTypeMapping ImportClass (XmlQualifiedName name)
\r
541 XmlTypeMapping map = ImportType (name, null, true);
\r
542 if (map.TypeData.SchemaType == SchemaTypes.Class) return map;
\r
543 XmlSchemaComplexType stype = schemas.Find (name, typeof (XmlSchemaComplexType)) as XmlSchemaComplexType;
\r
544 return CreateClassMap (name, stype, new XmlQualifiedName (map.ElementName, map.Namespace));
\r
547 XmlTypeMapping ImportType (XmlQualifiedName name, XmlSchemaType stype, XmlQualifiedName root)
\r
549 XmlTypeMapping map = GetRegisteredTypeMapping (name);
\r
551 XmlSchemaComplexType ct = stype as XmlSchemaComplexType;
\r
552 if (map.TypeData.SchemaType != SchemaTypes.Class || ct == null || !CanBeArray (name, ct)) {
\r
553 map.UpdateRoot (root);
\r
557 // The map was initially imported as a class, but it turns out that it is an
\r
558 // array. It has to be imported now as array.
\r
561 if (stype is XmlSchemaComplexType)
\r
562 return ImportClassComplexType (name, (XmlSchemaComplexType) stype, root);
\r
563 else if (stype is XmlSchemaSimpleType)
\r
564 return ImportClassSimpleType (name, (XmlSchemaSimpleType) stype, root);
\r
566 throw new NotSupportedException ("Schema type not supported: " + stype.GetType ());
\r
569 XmlTypeMapping ImportClassComplexType (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
\r
571 // The need for fixups: If the complex type is an array, then to get the type of the
\r
572 // array we need first to get the type of the items of the array.
\r
573 // But if one of the item types or its children has a referece to this type array,
\r
574 // then we enter in an infinite loop. This does not happen with class types because
\r
575 // the class map is registered before parsing the children. We can't do the same
\r
576 // with the array type because to register the array map we need the type of the array.
\r
578 Type anyType = GetAnyElementType (stype);
\r
579 if (anyType != null)
\r
580 return GetTypeMapping (TypeTranslator.GetTypeData(anyType));
\r
582 if (CanBeArray (typeQName, stype))
\r
585 ListMap listMap = BuildArrayMap (typeQName, stype, out typeData);
\r
586 if (listMap != null)
\r
588 XmlTypeMapping map = CreateArrayTypeMapping (typeQName, typeData);
\r
589 map.ObjectMap = listMap;
\r
593 // After all, it is not an array. Create a class map then.
\r
595 else if (CanBeIXmlSerializable (stype))
\r
597 return ImportXmlSerializableMapping (typeQName.Namespace);
\r
600 // Register the map right now but do not build it,
\r
601 // This will avoid loops.
\r
603 return CreateClassMap (typeQName, stype, root);
\r
606 XmlTypeMapping CreateClassMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, XmlQualifiedName root)
\r
608 XmlTypeMapping map = CreateTypeMapping (typeQName, SchemaTypes.Class, root);
\r
609 map.Documentation = GetDocumentation (stype);
\r
610 RegisterMapFixup (map, typeQName, stype);
\r
614 void RegisterMapFixup (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
\r
616 MapFixup fixup = new MapFixup ();
\r
618 fixup.SchemaType = stype;
\r
619 fixup.TypeName = typeQName;
\r
620 pendingMaps.Enqueue (fixup);
\r
623 void BuildPendingMaps ()
\r
625 while (pendingMaps.Count > 0) {
\r
626 MapFixup fixup = (MapFixup) pendingMaps.Dequeue ();
\r
627 if (fixup.Map.ObjectMap == null) {
\r
628 BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
\r
629 if (fixup.Map.ObjectMap == null) pendingMaps.Enqueue (fixup);
\r
634 void BuildPendingMap (XmlTypeMapping map)
\r
636 if (map.ObjectMap != null) return;
\r
638 foreach (MapFixup fixup in pendingMaps)
\r
640 if (fixup.Map == map) {
\r
641 BuildClassMap (fixup.Map, fixup.TypeName, fixup.SchemaType);
\r
645 throw new InvalidOperationException ("Can't complete map of type " + map.XmlType + " : " + map.Namespace);
\r
648 void BuildClassMap (XmlTypeMapping map, XmlQualifiedName typeQName, XmlSchemaComplexType stype)
\r
650 CodeIdentifiers classIds = new CodeIdentifiers();
\r
651 classIds.AddReserved (map.TypeData.TypeName);
\r
653 ClassMap cmap = new ClassMap ();
\r
654 map.ObjectMap = cmap;
\r
655 bool isMixed = stype.IsMixed;
\r
657 if (stype.Particle != null)
\r
658 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, isMixed);
\r
661 if (stype.ContentModel is XmlSchemaSimpleContent) {
\r
662 ImportSimpleContent (typeQName, map, (XmlSchemaSimpleContent)stype.ContentModel, classIds, isMixed);
\r
664 else if (stype.ContentModel is XmlSchemaComplexContent) {
\r
665 ImportComplexContent (typeQName, map, (XmlSchemaComplexContent)stype.ContentModel, classIds, isMixed);
\r
669 ImportAttributes (typeQName, cmap, stype.Attributes, stype.AnyAttribute, classIds);
\r
670 ImportExtensionTypes (typeQName);
\r
672 if (isMixed) AddTextMember (typeQName, cmap, classIds);
\r
674 AddObjectDerivedMap (map);
\r
677 void ImportAttributes (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection atts, XmlSchemaAnyAttribute anyat, CodeIdentifiers classIds)
\r
681 XmlTypeMapMemberAnyAttribute member = new XmlTypeMapMemberAnyAttribute ();
\r
682 member.Name = classIds.AddUnique ("AnyAttribute", member);
\r
683 member.TypeData = TypeTranslator.GetTypeData (typeof(XmlAttribute[]));
\r
684 cmap.AddMember (member);
\r
687 foreach (XmlSchemaObject at in atts)
\r
689 if (at is XmlSchemaAttribute)
\r
692 XmlSchemaAttribute attr = (XmlSchemaAttribute)at;
\r
693 XmlSchemaAttribute refAttr = GetRefAttribute (typeQName, attr, out ns);
\r
694 XmlTypeMapMemberAttribute member = new XmlTypeMapMemberAttribute ();
\r
695 member.Name = classIds.AddUnique (CodeIdentifier.MakeValid (refAttr.Name), member);
\r
696 member.Documentation = GetDocumentation (attr);
\r
697 member.AttributeName = refAttr.Name;
\r
698 member.Namespace = ns;
\r
699 member.Form = refAttr.Form;
\r
700 member.TypeData = GetAttributeTypeData (typeQName, attr);
\r
702 if (refAttr.DefaultValue != null)
\r
703 member.DefaultValue = ImportDefaultValue (member.TypeData, refAttr.DefaultValue);
\r
704 else if (member.TypeData.IsValueType)
\r
705 member.IsOptionalValueType = (refAttr.ValidatedUse != XmlSchemaUse.Required);
\r
707 if (member.TypeData.IsComplexType)
\r
708 member.MappedType = GetTypeMapping (member.TypeData);
\r
709 cmap.AddMember (member);
\r
711 else if (at is XmlSchemaAttributeGroupRef)
\r
713 XmlSchemaAttributeGroupRef gref = (XmlSchemaAttributeGroupRef)at;
\r
714 XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
\r
715 ImportAttributes (typeQName, cmap, grp.Attributes, grp.AnyAttribute, classIds);
\r
720 ListMap BuildArrayMap (XmlQualifiedName typeQName, XmlSchemaComplexType stype, out TypeData arrayTypeData)
\r
724 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
\r
725 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
\r
726 XmlSchemaAttribute arrayTypeAt = FindArrayAttribute (rest.Attributes);
\r
728 if (arrayTypeAt != null)
\r
730 XmlAttribute[] uatts = arrayTypeAt.UnhandledAttributes;
\r
731 if (uatts == null || uatts.Length == 0) throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
\r
733 XmlAttribute xat = null;
\r
734 foreach (XmlAttribute at in uatts)
\r
735 if (at.LocalName == "arrayType" && at.NamespaceURI == XmlSerializer.WsdlNamespace)
\r
736 { xat = at; break; }
\r
739 throw new InvalidOperationException ("arrayType attribute not specified in array declaration: " + typeQName);
\r
741 string name, ns, dims;
\r
742 TypeTranslator.ParseArrayType (xat.Value, out name, out ns, out dims);
\r
743 return BuildEncodedArrayMap (name + dims, ns, out arrayTypeData);
\r
747 XmlSchemaElement elem = null;
\r
748 XmlSchemaSequence seq = rest.Particle as XmlSchemaSequence;
\r
749 if (seq != null && seq.Items.Count == 1)
\r
750 elem = seq.Items[0] as XmlSchemaElement;
\r
752 XmlSchemaAll all = rest.Particle as XmlSchemaAll;
\r
753 if (all != null && all.Items.Count == 1)
\r
754 elem = all.Items[0] as XmlSchemaElement;
\r
757 throw new InvalidOperationException ("Unknown array format");
\r
759 return BuildEncodedArrayMap (elem.SchemaTypeName.Name + "[]", elem.SchemaTypeName.Namespace, out arrayTypeData);
\r
764 ClassMap cmap = new ClassMap ();
\r
765 CodeIdentifiers classIds = new CodeIdentifiers();
\r
766 ImportParticleComplexContent (typeQName, cmap, stype.Particle, classIds, stype.IsMixed);
\r
768 XmlTypeMapMemberFlatList list = (cmap.AllMembers.Count == 1) ? cmap.AllMembers[0] as XmlTypeMapMemberFlatList : null;
\r
769 if (list != null && list.ChoiceMember == null)
\r
771 arrayTypeData = list.TypeData;
\r
772 return list.ListMap;
\r
776 arrayTypeData = null;
\r
782 ListMap BuildEncodedArrayMap (string type, string ns, out TypeData arrayTypeData)
\r
784 ListMap map = new ListMap ();
\r
786 int i = type.LastIndexOf ("[");
\r
787 if (i == -1) throw new InvalidOperationException ("Invalid arrayType value: " + type);
\r
788 if (type.IndexOf (",",i) != -1) throw new InvalidOperationException ("Multidimensional arrays are not supported");
\r
790 string itemType = type.Substring (0,i);
\r
792 TypeData itemTypeData;
\r
793 if (itemType.IndexOf ("[") != -1)
\r
795 ListMap innerListMap = BuildEncodedArrayMap (itemType, ns, out itemTypeData);
\r
797 int dims = itemType.Split ('[').Length - 1;
\r
798 string name = TypeTranslator.GetArrayName (type, dims);
\r
799 XmlQualifiedName qname = new XmlQualifiedName (name, ns);
\r
800 XmlTypeMapping tmap = CreateArrayTypeMapping (qname, itemTypeData);
\r
801 tmap.ObjectMap = innerListMap;
\r
805 itemTypeData = GetTypeData (new XmlQualifiedName (itemType, ns), null);
\r
808 arrayTypeData = itemTypeData.ListTypeData;
\r
810 map.ItemInfo = new XmlTypeMapElementInfoList();
\r
811 map.ItemInfo.Add (CreateElementInfo ("", null, "Item", itemTypeData, true, XmlSchemaForm.None));
\r
815 XmlSchemaAttribute FindArrayAttribute (XmlSchemaObjectCollection atts)
\r
817 foreach (object ob in atts)
\r
819 XmlSchemaAttribute att = ob as XmlSchemaAttribute;
\r
820 if (att != null && att.RefName == arrayTypeRefName) return att;
\r
822 XmlSchemaAttributeGroupRef gref = ob as XmlSchemaAttributeGroupRef;
\r
825 XmlSchemaAttributeGroup grp = FindRefAttributeGroup (gref.RefName);
\r
826 att = FindArrayAttribute (grp.Attributes);
\r
827 if (att != null) return att;
\r
833 void ImportParticleComplexContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool isMixed)
\r
835 ImportParticleContent (typeQName, cmap, particle, classIds, false, ref isMixed);
\r
836 if (isMixed) AddTextMember (typeQName, cmap, classIds);
\r
839 void AddTextMember (XmlQualifiedName typeQName, ClassMap cmap, CodeIdentifiers classIds)
\r
841 if (cmap.XmlTextCollector == null)
\r
843 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
\r
844 member.Name = classIds.AddUnique ("Text", member);
\r
845 member.TypeData = TypeTranslator.GetTypeData (typeof(string[]));
\r
846 member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData.ListItemTypeData));
\r
847 member.IsXmlTextCollector = true;
\r
848 member.ListMap = new ListMap ();
\r
849 member.ListMap.ItemInfo = member.ElementInfo;
\r
850 cmap.AddMember (member);
\r
854 void ImportParticleContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaParticle particle, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
\r
856 if (particle == null) return;
\r
858 if (particle is XmlSchemaGroupRef)
\r
859 particle = GetRefGroupParticle ((XmlSchemaGroupRef)particle);
\r
861 if (particle.MaxOccurs > 1) multiValue = true;
\r
863 if (particle is XmlSchemaSequence) {
\r
864 ImportSequenceContent (typeQName, cmap, ((XmlSchemaSequence)particle).Items, classIds, multiValue, ref isMixed);
\r
866 else if (particle is XmlSchemaChoice) {
\r
867 if (((XmlSchemaChoice)particle).Items.Count == 1)
\r
868 ImportSequenceContent (typeQName, cmap, ((XmlSchemaChoice)particle).Items, classIds, multiValue, ref isMixed);
\r
870 ImportChoiceContent (typeQName, cmap, (XmlSchemaChoice)particle, classIds, multiValue);
\r
872 else if (particle is XmlSchemaAll) {
\r
873 ImportSequenceContent (typeQName, cmap, ((XmlSchemaAll)particle).Items, classIds, multiValue, ref isMixed);
\r
877 void ImportSequenceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaObjectCollection items, CodeIdentifiers classIds, bool multiValue, ref bool isMixed)
\r
879 foreach (XmlSchemaObject item in items)
\r
881 if (item is XmlSchemaElement)
\r
884 XmlSchemaElement elem = (XmlSchemaElement) item;
\r
885 XmlTypeMapping emap;
\r
886 TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
\r
887 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
\r
889 if (elem.MaxOccurs == 1 && !multiValue)
\r
891 XmlTypeMapMemberElement member = null;
\r
892 if (typeData.SchemaType != SchemaTypes.Array)
\r
894 member = new XmlTypeMapMemberElement ();
\r
895 if (refElem.DefaultValue != null) member.DefaultValue = ImportDefaultValue (typeData, refElem.DefaultValue);
\r
897 else if (GetTypeMapping (typeData).IsSimpleType)
\r
899 // It is a simple list (space separated list).
\r
900 // Since this is not supported, map as a single item value
\r
901 member = new XmlTypeMapMemberElement ();
\r
903 // In MS.NET those types are mapped to a string
\r
904 typeData = TypeTranslator.GetTypeData(typeof(string));
\r
906 typeData = typeData.ListItemTypeData;
\r
910 member = new XmlTypeMapMemberList ();
\r
912 if (elem.MinOccurs == 0 && typeData.IsValueType)
\r
913 member.IsOptionalValueType = true;
\r
915 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
\r
916 member.Documentation = GetDocumentation (elem);
\r
917 member.TypeData = typeData;
\r
918 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
\r
919 cmap.AddMember (member);
\r
923 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
\r
924 member.ListMap = new ListMap ();
\r
925 member.Name = classIds.AddUnique(CodeIdentifier.MakeValid(refElem.Name), member);
\r
926 member.Documentation = GetDocumentation (elem);
\r
927 member.TypeData = typeData.ListTypeData;
\r
928 member.ElementInfo.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
\r
929 member.ListMap.ItemInfo = member.ElementInfo;
\r
930 cmap.AddMember (member);
\r
933 else if (item is XmlSchemaAny)
\r
935 XmlSchemaAny elem = (XmlSchemaAny) item;
\r
936 XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement ();
\r
937 member.Name = classIds.AddUnique ("Any", member);
\r
938 member.Documentation = GetDocumentation (elem);
\r
941 if (elem.MaxOccurs != 1 || multiValue)
\r
942 ctype = isMixed ? typeof(XmlNode[]) : typeof(XmlElement[]);
\r
944 ctype = isMixed ? typeof(XmlNode) : typeof(XmlElement);
\r
946 member.TypeData = TypeTranslator.GetTypeData (ctype);
\r
947 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, member.TypeData);
\r
948 einfo.IsUnnamedAnyElement = true;
\r
949 member.ElementInfo.Add (einfo);
\r
953 einfo = CreateTextElementInfo (typeQName.Namespace, member, member.TypeData);
\r
954 member.ElementInfo.Add (einfo);
\r
955 member.IsXmlTextCollector = true;
\r
956 isMixed = false; //Allow only one XmlTextAttribute
\r
959 cmap.AddMember (member);
\r
961 else if (item is XmlSchemaParticle) {
\r
962 ImportParticleContent (typeQName, cmap, (XmlSchemaParticle)item, classIds, multiValue, ref isMixed);
\r
967 object ImportDefaultValue (TypeData typeData, string value)
\r
969 if (typeData.SchemaType == SchemaTypes.Enum) {
\r
970 XmlTypeMapping map = GetTypeMapping (typeData);
\r
971 EnumMap emap = (EnumMap) map.ObjectMap;
\r
972 string res = emap.GetEnumName (map.TypeFullName, value);
\r
973 if (res == null) throw new InvalidOperationException ("'" + value + "' is not a valid enumeration value");
\r
976 return XmlCustomFormatter.FromXmlString (typeData, value);
\r
979 void ImportChoiceContent (XmlQualifiedName typeQName, ClassMap cmap, XmlSchemaChoice choice, CodeIdentifiers classIds, bool multiValue)
\r
981 XmlTypeMapElementInfoList choices = new XmlTypeMapElementInfoList ();
\r
982 multiValue = ImportChoices (typeQName, null, choices, choice.Items) || multiValue;
\r
983 if (choices.Count == 0) return;
\r
985 if (choice.MaxOccurs > 1) multiValue = true;
\r
987 XmlTypeMapMemberElement member;
\r
990 member = new XmlTypeMapMemberFlatList ();
\r
991 member.Name = classIds.AddUnique ("Items", member);
\r
992 ListMap listMap = new ListMap ();
\r
993 listMap.ItemInfo = choices;
\r
994 ((XmlTypeMapMemberFlatList)member).ListMap = listMap;
\r
998 member = new XmlTypeMapMemberElement ();
\r
999 member.Name = classIds.AddUnique ("Item", member);
\r
1002 // If all choices have the same type, use that type for the member.
\r
1003 // If not use System.Object.
\r
1004 // If there are at least two choices with the same type, use a choice
\r
1005 // identifier attribute
\r
1007 TypeData typeData = null;
\r
1008 bool twoEqual = false;
\r
1009 bool allEqual = true;
\r
1010 Hashtable types = new Hashtable ();
\r
1012 for (int n = choices.Count - 1; n >= 0; n--)
\r
1014 XmlTypeMapElementInfo einfo = (XmlTypeMapElementInfo) choices [n];
\r
1016 // In some complex schemas, we may end up with several options
\r
1017 // with the same name. It is better to ignore the extra options
\r
1018 // than to crash. It's the best we can do, and btw it works
\r
1019 // better than in MS.NET.
\r
1021 if (cmap.GetElement (einfo.ElementName, einfo.Namespace) != null ||
\r
1022 choices.IndexOfElement (einfo.ElementName, einfo.Namespace) != n)
\r
1024 choices.RemoveAt (n);
\r
1028 if (types.ContainsKey (einfo.TypeData)) twoEqual = true;
\r
1029 else types.Add (einfo.TypeData, einfo);
\r
1031 TypeData choiceType = einfo.TypeData;
\r
1032 if (choiceType.SchemaType == SchemaTypes.Class)
\r
1034 // When comparing class types, use the most generic class in the
\r
1035 // inheritance hierarchy
\r
1037 XmlTypeMapping choiceMap = GetTypeMapping (choiceType);
\r
1038 BuildPendingMap (choiceMap);
\r
1039 while (choiceMap.BaseMap != null) {
\r
1040 choiceMap = choiceMap.BaseMap;
\r
1041 BuildPendingMap (choiceMap);
\r
1042 choiceType = choiceMap.TypeData;
\r
1046 if (typeData == null) typeData = choiceType;
\r
1047 else if (typeData != choiceType) allEqual = false;
\r
1051 typeData = TypeTranslator.GetTypeData (typeof(object));
\r
1055 // Create the choice member
\r
1056 XmlTypeMapMemberElement choiceMember = new XmlTypeMapMemberElement ();
\r
1057 choiceMember.Ignore = true;
\r
1058 choiceMember.Name = classIds.AddUnique (member.Name + "ElementName", choiceMember);
\r
1059 member.ChoiceMember = choiceMember.Name;
\r
1061 // Create the choice enum
\r
1062 XmlTypeMapping enumMap = CreateTypeMapping (new XmlQualifiedName (member.Name + "ChoiceType", typeQName.Namespace), SchemaTypes.Enum, null);
\r
1063 enumMap.IncludeInSchema = false;
\r
1065 CodeIdentifiers codeIdents = new CodeIdentifiers ();
\r
1066 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [choices.Count];
\r
1067 for (int n=0; n<choices.Count; n++)
\r
1069 XmlTypeMapElementInfo it =(XmlTypeMapElementInfo) choices[n];
\r
1070 bool extraNs = (it.Namespace != null && it.Namespace != "" && it.Namespace != typeQName.Namespace);
\r
1071 string xmlName = extraNs ? it.Namespace + ":" + it.ElementName : it.ElementName;
\r
1072 string enumName = codeIdents.AddUnique (CodeIdentifier.MakeValid (it.ElementName), it);
\r
1073 members [n] = new EnumMap.EnumMapMember (xmlName, enumName);
\r
1075 enumMap.ObjectMap = new EnumMap (members, false);
\r
1077 choiceMember.TypeData = multiValue ? enumMap.TypeData.ListTypeData : enumMap.TypeData;
\r
1078 choiceMember.ElementInfo.Add (CreateElementInfo (typeQName.Namespace, choiceMember, choiceMember.Name, choiceMember.TypeData, false, XmlSchemaForm.None));
\r
1079 cmap.AddMember (choiceMember);
\r
1082 if (typeData == null)
\r
1086 typeData = typeData.ListTypeData;
\r
1088 member.ElementInfo = choices;
\r
1089 member.Documentation = GetDocumentation (choice);
\r
1090 member.TypeData = typeData;
\r
1091 cmap.AddMember (member);
\r
1094 bool ImportChoices (XmlQualifiedName typeQName, XmlTypeMapMember member, XmlTypeMapElementInfoList choices, XmlSchemaObjectCollection items)
\r
1096 bool multiValue = false;
\r
1097 foreach (XmlSchemaObject titem in items)
\r
1099 XmlSchemaObject item = titem;
\r
1100 if (item is XmlSchemaGroupRef)
\r
1101 item = GetRefGroupParticle ((XmlSchemaGroupRef)item);
\r
1103 if (item is XmlSchemaElement)
\r
1106 XmlSchemaElement elem = (XmlSchemaElement) item;
\r
1107 XmlTypeMapping emap;
\r
1108 TypeData typeData = GetElementTypeData (typeQName, elem, null, out emap);
\r
1109 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
\r
1110 choices.Add (CreateElementInfo (ns, member, refElem.Name, typeData, refElem.IsNillable, refElem.Form, emap));
\r
1111 if (elem.MaxOccurs > 1) multiValue = true;
\r
1113 else if (item is XmlSchemaAny)
\r
1115 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));
\r
1116 einfo.IsUnnamedAnyElement = true;
\r
1117 choices.Add (einfo);
\r
1119 else if (item is XmlSchemaChoice) {
\r
1120 multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaChoice)item).Items) || multiValue;
\r
1122 else if (item is XmlSchemaSequence) {
\r
1123 multiValue = ImportChoices (typeQName, member, choices, ((XmlSchemaSequence)item).Items) || multiValue;
\r
1126 return multiValue;
\r
1129 void ImportSimpleContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaSimpleContent content, CodeIdentifiers classIds, bool isMixed)
\r
1131 XmlSchemaSimpleContentExtension ext = content.Content as XmlSchemaSimpleContentExtension;
\r
1132 ClassMap cmap = (ClassMap)map.ObjectMap;
\r
1133 XmlQualifiedName qname = GetContentBaseType (content.Content);
\r
1134 TypeData simpleType = null;
\r
1136 if (!IsPrimitiveTypeNamespace (qname.Namespace))
\r
1138 // Add base map members to this map
\r
1140 XmlTypeMapping baseMap = ImportType (qname, null, true);
\r
1141 BuildPendingMap (baseMap);
\r
1143 if (baseMap.IsSimpleType) {
\r
1144 simpleType = baseMap.TypeData;
\r
1146 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
\r
1148 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
\r
1149 cmap.AddMember (member);
\r
1151 map.BaseMap = baseMap;
\r
1152 baseMap.DerivedTypes.Add (map);
\r
1156 simpleType = FindBuiltInType (qname);
\r
1158 if (simpleType != null) {
\r
1159 XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
\r
1160 member.Name = classIds.AddUnique("Value", member);
\r
1161 member.TypeData = simpleType;
\r
1162 member.ElementInfo.Add (CreateTextElementInfo (typeQName.Namespace, member, member.TypeData));
\r
1163 member.IsXmlTextCollector = true;
\r
1164 cmap.AddMember (member);
\r
1168 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
\r
1171 TypeData FindBuiltInType (XmlQualifiedName qname)
\r
1173 XmlSchemaComplexType ct = (XmlSchemaComplexType) schemas.Find (qname, typeof(XmlSchemaComplexType));
\r
1176 XmlSchemaSimpleContent sc = ct.ContentModel as XmlSchemaSimpleContent;
\r
1177 if (sc == null) throw new InvalidOperationException ("Invalid schema");
\r
1178 return FindBuiltInType (GetContentBaseType (sc.Content));
\r
1181 XmlSchemaSimpleType st = (XmlSchemaSimpleType) schemas.Find (qname, typeof(XmlSchemaSimpleType));
\r
1183 return FindBuiltInType (qname, st);
\r
1185 if (IsPrimitiveTypeNamespace (qname.Namespace))
\r
1186 return TypeTranslator.GetPrimitiveTypeData (qname.Name);
\r
1188 throw new InvalidOperationException ("Definition of type '" + qname + "' not found");
\r
1191 TypeData FindBuiltInType (XmlQualifiedName qname, XmlSchemaSimpleType st)
\r
1193 if (CanBeEnum (st) && qname != null)
\r
1194 return ImportType (qname, null, true).TypeData;
\r
1196 if (st.Content is XmlSchemaSimpleTypeRestriction) {
\r
1197 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction) st.Content;
\r
1198 XmlQualifiedName bn = GetContentBaseType (rest);
\r
1199 if (bn == XmlQualifiedName.Empty && rest.BaseType != null)
\r
1200 return FindBuiltInType (qname, rest.BaseType);
\r
1202 return FindBuiltInType (bn);
\r
1204 else if (st.Content is XmlSchemaSimpleTypeList) {
\r
1205 return FindBuiltInType (GetContentBaseType (st.Content)).ListTypeData;
\r
1207 else if (st.Content is XmlSchemaSimpleTypeUnion) {
\r
1208 // MS.NET always import simple unions as string
\r
1209 return FindBuiltInType (new XmlQualifiedName ("string", XmlSchema.Namespace));
\r
1215 XmlQualifiedName GetContentBaseType (XmlSchemaObject ob)
\r
1217 if (ob is XmlSchemaSimpleContentExtension)
\r
1218 return ((XmlSchemaSimpleContentExtension)ob).BaseTypeName;
\r
1219 else if (ob is XmlSchemaSimpleContentRestriction)
\r
1220 return ((XmlSchemaSimpleContentRestriction)ob).BaseTypeName;
\r
1221 else if (ob is XmlSchemaSimpleTypeRestriction)
\r
1222 return ((XmlSchemaSimpleTypeRestriction)ob).BaseTypeName;
\r
1223 else if (ob is XmlSchemaSimpleTypeList)
\r
1224 return ((XmlSchemaSimpleTypeList)ob).ItemTypeName;
\r
1229 void ImportComplexContent (XmlQualifiedName typeQName, XmlTypeMapping map, XmlSchemaComplexContent content, CodeIdentifiers classIds, bool isMixed)
\r
1231 ClassMap cmap = (ClassMap)map.ObjectMap;
\r
1232 XmlQualifiedName qname;
\r
1234 XmlSchemaComplexContentExtension ext = content.Content as XmlSchemaComplexContentExtension;
\r
1235 if (ext != null) qname = ext.BaseTypeName;
\r
1236 else qname = ((XmlSchemaComplexContentRestriction)content.Content).BaseTypeName;
\r
1238 if (qname == typeQName)
\r
1239 throw new InvalidOperationException ("Cannot import schema for type '" + typeQName.Name + "' from namespace '" + typeQName.Namespace + "'. Redefine not supported");
\r
1241 // Add base map members to this map
\r
1243 XmlTypeMapping baseMap = ImportClass (qname);
\r
1244 BuildPendingMap (baseMap);
\r
1245 ClassMap baseClassMap = (ClassMap)baseMap.ObjectMap;
\r
1247 foreach (XmlTypeMapMember member in baseClassMap.AllMembers)
\r
1248 cmap.AddMember (member);
\r
1250 if (baseClassMap.XmlTextCollector != null) isMixed = false;
\r
1251 else if (content.IsMixed) isMixed = true;
\r
1253 map.BaseMap = baseMap;
\r
1254 baseMap.DerivedTypes.Add (map);
\r
1256 if (ext != null) {
\r
1257 // Add the members of this map
\r
1258 ImportParticleComplexContent (typeQName, cmap, ext.Particle, classIds, isMixed);
\r
1259 ImportAttributes (typeQName, cmap, ext.Attributes, ext.AnyAttribute, classIds);
\r
1262 if (isMixed) ImportParticleComplexContent (typeQName, cmap, null, classIds, true);
\r
1266 void ImportExtensionTypes (XmlQualifiedName qname)
\r
1268 foreach (XmlSchema schema in schemas) {
\r
1269 foreach (XmlSchemaObject sob in schema.Items)
\r
1271 XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
\r
1272 if (sct != null && sct.ContentModel is XmlSchemaComplexContent) {
\r
1273 XmlQualifiedName exqname;
\r
1274 XmlSchemaComplexContentExtension ext = sct.ContentModel.Content as XmlSchemaComplexContentExtension;
\r
1275 if (ext != null) exqname = ext.BaseTypeName;
\r
1276 else exqname = ((XmlSchemaComplexContentRestriction)sct.ContentModel.Content).BaseTypeName;
\r
1277 if (exqname == qname)
\r
1278 ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
\r
1284 XmlTypeMapping ImportClassSimpleType (XmlQualifiedName typeQName, XmlSchemaSimpleType stype, XmlQualifiedName root)
\r
1286 if (CanBeEnum (stype))
\r
1288 // Create an enum map
\r
1290 CodeIdentifiers codeIdents = new CodeIdentifiers ();
\r
1291 XmlTypeMapping enumMap = CreateTypeMapping (typeQName, SchemaTypes.Enum, null);
\r
1292 enumMap.Documentation = GetDocumentation (stype);
\r
1294 bool isFlags = false;
\r
1295 if (stype.Content is XmlSchemaSimpleTypeList) {
\r
1296 stype = ((XmlSchemaSimpleTypeList)stype.Content).ItemType;
\r
1299 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;
\r
1301 codeIdents.AddReserved (enumMap.TypeData.TypeName);
\r
1303 EnumMap.EnumMapMember[] members = new EnumMap.EnumMapMember [rest.Facets.Count];
\r
1304 for (int n=0; n<rest.Facets.Count; n++)
\r
1306 XmlSchemaEnumerationFacet enu = (XmlSchemaEnumerationFacet) rest.Facets[n];
\r
1307 string enumName = codeIdents.AddUnique(CodeIdentifier.MakeValid (enu.Value), enu);
\r
1308 members [n] = new EnumMap.EnumMapMember (enu.Value, enumName);
\r
1309 members [n].Documentation = GetDocumentation (enu);
\r
1311 enumMap.ObjectMap = new EnumMap (members, isFlags);
\r
1312 enumMap.IsSimpleType = true;
\r
1316 if (stype.Content is XmlSchemaSimpleTypeList)
\r
1318 XmlSchemaSimpleTypeList slist = (XmlSchemaSimpleTypeList)stype.Content;
\r
1319 TypeData arrayTypeData = FindBuiltInType (slist.ItemTypeName, stype);
\r
1321 ListMap listMap = new ListMap ();
\r
1323 listMap.ItemInfo = new XmlTypeMapElementInfoList ();
\r
1324 listMap.ItemInfo.Add (CreateElementInfo (typeQName.Namespace, null, "Item", arrayTypeData.ListItemTypeData, false, XmlSchemaForm.None));
\r
1326 XmlTypeMapping map = CreateArrayTypeMapping (typeQName, arrayTypeData);
\r
1327 map.ObjectMap = listMap;
\r
1328 map.IsSimpleType = true;
\r
1332 // It is an extension of a primitive or known type
\r
1334 TypeData typeData = FindBuiltInType (typeQName, stype);
\r
1335 XmlTypeMapping rmap = GetTypeMapping (typeData);
\r
1337 // The resulting map must be a simple type. It needs to be explicitely set for arrays
\r
1338 rmap.IsSimpleType = true;
\r
1342 bool CanBeEnum (XmlSchemaSimpleType stype)
\r
1344 if (stype.Content is XmlSchemaSimpleTypeRestriction)
\r
1346 XmlSchemaSimpleTypeRestriction rest = (XmlSchemaSimpleTypeRestriction)stype.Content;
\r
1347 if (rest.Facets.Count == 0) return false;
\r
1348 foreach (object ob in rest.Facets)
\r
1349 if (!(ob is XmlSchemaEnumerationFacet)) return false;
\r
1352 else if (stype.Content is XmlSchemaSimpleTypeList)
\r
1354 XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList) stype.Content;
\r
1355 return (list.ItemType != null && CanBeEnum (list.ItemType));
\r
1360 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaComplexType stype)
\r
1362 if (encodedFormat)
\r
1364 XmlSchemaComplexContent content = stype.ContentModel as XmlSchemaComplexContent;
\r
1365 if (content == null) return false;
\r
1366 XmlSchemaComplexContentRestriction rest = content.Content as XmlSchemaComplexContentRestriction;
\r
1367 if (rest == null) return false;
\r
1368 return rest.BaseTypeName == arrayType;
\r
1372 if (stype.Attributes.Count > 0 || stype.AnyAttribute != null) return false;
\r
1373 else return !stype.IsMixed && CanBeArray (typeQName, stype.Particle, false);
\r
1377 bool CanBeArray (XmlQualifiedName typeQName, XmlSchemaParticle particle, bool multiValue)
\r
1379 // To be an array, there can't be a direct child of type typeQName
\r
1381 if (particle == null) return false;
\r
1383 multiValue = multiValue || particle.MaxOccurs > 1;
\r
1385 if (particle is XmlSchemaGroupRef)
\r
1386 return CanBeArray (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), multiValue);
\r
1388 if (particle is XmlSchemaElement)
\r
1390 XmlSchemaElement elem = (XmlSchemaElement)particle;
\r
1391 if (!elem.RefName.IsEmpty)
\r
1392 return CanBeArray (typeQName, FindRefElement (elem), multiValue);
\r
1394 return multiValue && !typeQName.Equals (((XmlSchemaElement)particle).SchemaTypeName);
\r
1397 if (particle is XmlSchemaAny)
\r
1398 return multiValue;
\r
1400 if (particle is XmlSchemaSequence)
\r
1402 XmlSchemaSequence seq = particle as XmlSchemaSequence;
\r
1403 if (seq.Items.Count != 1) return false;
\r
1404 return CanBeArray (typeQName, (XmlSchemaParticle)seq.Items[0], multiValue);
\r
1407 if (particle is XmlSchemaChoice)
\r
1409 // Can be array if all choices have different types
\r
1410 ArrayList types = new ArrayList ();
\r
1411 if(!CheckChoiceType (typeQName, particle, types, ref multiValue)) return false;
\r
1412 return multiValue;
\r
1418 bool CheckChoiceType (XmlQualifiedName typeQName, XmlSchemaParticle particle, ArrayList types, ref bool multiValue)
\r
1420 XmlQualifiedName type = null;
\r
1422 multiValue = multiValue || particle.MaxOccurs > 1;
\r
1424 if (particle is XmlSchemaGroupRef)
\r
1425 return CheckChoiceType (typeQName, GetRefGroupParticle ((XmlSchemaGroupRef)particle), types, ref multiValue);
\r
1427 if (particle is XmlSchemaElement) {
\r
1429 XmlSchemaElement elem = (XmlSchemaElement)particle;
\r
1430 XmlSchemaElement refElem = GetRefElement (typeQName, elem, out ns);
\r
1431 if (refElem.SchemaType != null) return true;
\r
1432 type = refElem.SchemaTypeName;
\r
1434 else if (particle is XmlSchemaAny) {
\r
1437 else if (particle is XmlSchemaSequence)
\r
1439 XmlSchemaSequence seq = particle as XmlSchemaSequence;
\r
1440 foreach (XmlSchemaParticle par in seq.Items)
\r
1441 if (!CheckChoiceType (typeQName, par, types, ref multiValue)) return false;
\r
1444 else if (particle is XmlSchemaChoice)
\r
1446 foreach (XmlSchemaParticle choice in ((XmlSchemaChoice)particle).Items)
\r
1447 if (!CheckChoiceType (typeQName, choice, types, ref multiValue)) return false;
\r
1451 if (typeQName.Equals (type)) return false;
\r
1453 // For primitive types, compare using CLR types, since several
\r
1454 // xml types can be mapped to a single CLR type
\r
1457 if (IsPrimitiveTypeNamespace (type.Namespace))
\r
1458 t = TypeTranslator.GetPrimitiveTypeData (type.Name).FullTypeName + ":" + type.Namespace;
\r
1461 t = type.Name + ":" + type.Namespace;
\r
1463 if (types.Contains (t)) return false;
\r
1468 bool CanBeAnyElement (XmlSchemaComplexType stype)
\r
1470 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
\r
1471 return (seq != null) && (seq.Items.Count == 1) && (seq.Items[0] is XmlSchemaAny);
\r
1474 Type GetAnyElementType (XmlSchemaComplexType stype)
\r
1476 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
\r
1478 if ((seq == null) || (seq.Items.Count != 1) || !(seq.Items[0] is XmlSchemaAny))
\r
1481 if (encodedFormat)
\r
1482 return typeof(object);
\r
1484 XmlSchemaAny any = seq.Items[0] as XmlSchemaAny;
\r
1485 if (any.MaxOccurs == 1)
\r
1487 if (stype.IsMixed)
\r
1488 return typeof(XmlNode);
\r
1490 return typeof(XmlElement);
\r
1494 if (stype.IsMixed)
\r
1495 return typeof(XmlNode[]);
\r
1497 return typeof(XmlElement[]);
\r
1501 bool CanBeIXmlSerializable (XmlSchemaComplexType stype)
\r
1503 XmlSchemaSequence seq = stype.Particle as XmlSchemaSequence;
\r
1504 if (seq == null) return false;
\r
1505 if (seq.Items.Count != 2) return false;
\r
1506 XmlSchemaElement elem = seq.Items[0] as XmlSchemaElement;
\r
1507 if (elem == null) return false;
\r
1508 if (elem.RefName != new XmlQualifiedName ("schema",XmlSchema.Namespace)) return false;
\r
1509 return (seq.Items[1] is XmlSchemaAny);
\r
1512 XmlTypeMapping ImportXmlSerializableMapping (string ns)
\r
1514 XmlQualifiedName qname = new XmlQualifiedName ("System.Data.DataSet",ns);
\r
1515 XmlTypeMapping map = mappedTypes [qname] as XmlTypeMapping;
\r
1516 if (map != null) return map;
\r
1518 TypeData typeData = new TypeData ("System.Data.DataSet", "System.Data.DataSet", "System.Data.DataSet", SchemaTypes.XmlSerializable, null);
\r
1519 map = new XmlTypeMapping ("System.Data.DataSet", "", typeData, "System.Data.DataSet", ns);
\r
1520 map.IncludeInSchema = true;
\r
1521 mappedTypes [qname] = map;
\r
1522 dataMappedTypes [typeData] = map;
\r
1526 XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form)
\r
1528 if (typeData.IsComplexType)
\r
1529 return CreateElementInfo (ns, member, name, typeData, isNillable, form, GetTypeMapping (typeData));
\r
1531 return CreateElementInfo (ns, member, name, typeData, isNillable, form, null);
\r
1534 XmlTypeMapElementInfo CreateElementInfo (string ns, XmlTypeMapMember member, string name, TypeData typeData, bool isNillable, XmlSchemaForm form, XmlTypeMapping emap)
\r
1536 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
\r
1537 einfo.ElementName = name;
\r
1538 einfo.Namespace = ns;
\r
1539 einfo.IsNullable = isNillable;
\r
1540 einfo.Form = form;
\r
1541 if (typeData.IsComplexType)
\r
1542 einfo.MappedType = emap;
\r
1546 XmlTypeMapElementInfo CreateTextElementInfo (string ns, XmlTypeMapMember member, TypeData typeData)
\r
1548 XmlTypeMapElementInfo einfo = new XmlTypeMapElementInfo (member, typeData);
\r
1549 einfo.IsTextElement = true;
\r
1550 einfo.WrappedElement = false;
\r
1551 if (typeData.IsComplexType)
\r
1552 einfo.MappedType = GetTypeMapping (typeData);
\r
1556 XmlTypeMapping CreateTypeMapping (XmlQualifiedName typeQName, SchemaTypes schemaType, XmlQualifiedName root)
\r
1558 string typeName = CodeIdentifier.MakeValid (typeQName.Name);
\r
1559 typeName = typeIdentifiers.AddUnique (typeName, null);
\r
1561 TypeData typeData = new TypeData (typeName, typeName, typeName, schemaType, null);
\r
1565 if (root != null) {
\r
1566 rootElem = root.Name;
\r
1567 rootNs = root.Namespace;
\r
1570 rootElem = typeQName.Name;
\r
1574 XmlTypeMapping map = new XmlTypeMapping (rootElem, rootNs, typeData, typeQName.Name, typeQName.Namespace);
\r
1575 map.IncludeInSchema = true;
\r
1576 mappedTypes [typeQName] = map;
\r
1577 dataMappedTypes [typeData] = map;
\r
1582 XmlTypeMapping CreateArrayTypeMapping (XmlQualifiedName typeQName, TypeData arrayTypeData)
\r
1584 XmlTypeMapping map;
\r
1585 if (encodedFormat) map = new XmlTypeMapping ("Array", XmlSerializer.EncodingNamespace, arrayTypeData, "Array", XmlSerializer.EncodingNamespace);
\r
1586 else map = new XmlTypeMapping (arrayTypeData.XmlType, typeQName.Namespace, arrayTypeData, arrayTypeData.XmlType, typeQName.Namespace);
\r
1588 map.IncludeInSchema = true;
\r
1589 mappedTypes [typeQName] = map;
\r
1590 dataMappedTypes [arrayTypeData] = map;
\r
1595 XmlSchemaElement GetRefElement (XmlQualifiedName typeQName, XmlSchemaElement elem, out string ns)
\r
1598 if (!elem.RefName.IsEmpty)
\r
1600 ns = elem.RefName.Namespace;
\r
1601 return FindRefElement (elem);
\r
1605 ns = typeQName.Namespace;
\r
1610 XmlSchemaAttribute GetRefAttribute (XmlQualifiedName typeQName, XmlSchemaAttribute attr, out string ns)
\r
1612 if (!attr.RefName.IsEmpty)
\r
1614 ns = attr.RefName.Namespace;
\r
1615 XmlSchemaAttribute at = FindRefAttribute (attr.RefName);
\r
1616 if (at == null) throw new InvalidOperationException ("The attribute " + attr.RefName + " is missing");
\r
1621 ns = typeQName.Namespace;
\r
1626 TypeData GetElementTypeData (XmlQualifiedName typeQName, XmlSchemaElement elem, XmlQualifiedName root, out XmlTypeMapping map)
\r
1628 bool sharedAnnType = false;
\r
1631 if (!elem.RefName.IsEmpty) {
\r
1632 XmlSchemaElement refElem = FindRefElement (elem);
\r
1633 if (refElem == null) throw new InvalidOperationException ("Global element not found: " + elem.RefName);
\r
1634 root = elem.RefName;
\r
1636 sharedAnnType = true;
\r
1640 if (!elem.SchemaTypeName.IsEmpty) {
\r
1641 td = GetTypeData (elem.SchemaTypeName, root);
\r
1642 map = GetRegisteredTypeMapping (elem.SchemaTypeName);
\r
1644 else if (elem.SchemaType == null)
\r
1645 td = TypeTranslator.GetTypeData (typeof(object));
\r
1647 td = GetTypeData (elem.SchemaType, typeQName, elem.Name, sharedAnnType, root);
\r
1649 if (map == null && td.IsComplexType)
\r
1650 map = GetTypeMapping (td);
\r
1655 TypeData GetAttributeTypeData (XmlQualifiedName typeQName, XmlSchemaAttribute attr)
\r
1657 bool sharedAnnType = false;
\r
1659 if (!attr.RefName.IsEmpty) {
\r
1660 XmlSchemaAttribute refAtt = FindRefAttribute (attr.RefName);
\r
1661 if (refAtt == null) throw new InvalidOperationException ("Global attribute not found: " + attr.RefName);
\r
1663 sharedAnnType = true;
\r
1666 if (!attr.SchemaTypeName.IsEmpty) return GetTypeData (attr.SchemaTypeName, null);
\r
1667 if (attr.SchemaType == null) return TypeTranslator.GetTypeData (typeof(string));
\r
1668 else return GetTypeData (attr.SchemaType, typeQName, attr.Name, sharedAnnType, null);
\r
1671 TypeData GetTypeData (XmlQualifiedName typeQName, XmlQualifiedName root)
\r
1673 if (IsPrimitiveTypeNamespace (typeQName.Namespace)) {
\r
1674 XmlTypeMapping map = ImportType (typeQName, root, false);
\r
1675 if (map != null) return map.TypeData;
\r
1676 else return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);
\r
1679 if (encodedFormat && typeQName.Namespace == "")
\r
1680 return TypeTranslator.GetPrimitiveTypeData (typeQName.Name);
\r
1682 return ImportType (typeQName, root, true).TypeData;
\r
1685 TypeData GetTypeData (XmlSchemaType stype, XmlQualifiedName typeQNname, string propertyName, bool sharedAnnType, XmlQualifiedName root)
\r
1689 if (sharedAnnType)
\r
1691 // Anonymous types defined in root elements or attributes can be shared among all elements that
\r
1692 // reference this root element or attribute
\r
1693 TypeData std = sharedAnonymousTypes [stype] as TypeData;
\r
1694 if (std != null) return std;
\r
1695 baseName = propertyName;
\r
1698 baseName = typeQNname.Name + typeIdentifiers.MakeRightCase (propertyName);
\r
1700 baseName = elemIdentifiers.AddUnique (baseName, stype);
\r
1702 XmlQualifiedName newName;
\r
1703 newName = new XmlQualifiedName (baseName, typeQNname.Namespace);
\r
1705 XmlTypeMapping map = ImportType (newName, stype, root);
\r
1706 if (sharedAnnType) sharedAnonymousTypes [stype] = map.TypeData;
\r
1708 return map.TypeData;
\r
1711 XmlTypeMapping GetTypeMapping (TypeData typeData)
\r
1713 if (typeData.Type == typeof(object) && !anyTypeImported)
\r
1714 ImportAllObjectTypes ();
\r
1716 XmlTypeMapping map = (XmlTypeMapping) dataMappedTypes [typeData];
\r
1717 if (map != null) return map;
\r
1719 if (typeData.IsListType)
\r
1721 // Create an array map for the type
\r
1723 XmlTypeMapping itemMap = GetTypeMapping (typeData.ListItemTypeData);
\r
1725 map = new XmlTypeMapping (typeData.XmlType, itemMap.Namespace, typeData, typeData.XmlType, itemMap.Namespace);
\r
1726 map.IncludeInSchema = true;
\r
1728 ListMap listMap = new ListMap ();
\r
1729 listMap.ItemInfo = new XmlTypeMapElementInfoList();
\r
1730 listMap.ItemInfo.Add (CreateElementInfo (itemMap.Namespace, null, typeData.ListItemTypeData.XmlType, typeData.ListItemTypeData, false, XmlSchemaForm.None));
\r
1731 map.ObjectMap = listMap;
\r
1733 mappedTypes [new XmlQualifiedName(map.ElementName, map.Namespace)] = map;
\r
1734 dataMappedTypes [typeData] = map;
\r
1737 else if (typeData.SchemaType == SchemaTypes.Primitive || typeData.Type == typeof(object) || typeof(XmlNode).IsAssignableFrom(typeData.Type))
\r
1739 return CreateSystemMap (typeData);
\r
1742 throw new InvalidOperationException ("Map for type " + typeData.TypeName + " not found");
\r
1745 void AddObjectDerivedMap (XmlTypeMapping map)
\r
1747 TypeData typeData = TypeTranslator.GetTypeData (typeof(object));
\r
1748 XmlTypeMapping omap = (XmlTypeMapping) dataMappedTypes [typeData];
\r
1750 omap = CreateSystemMap (typeData);
\r
1751 omap.DerivedTypes.Add (map);
\r
1754 XmlTypeMapping CreateSystemMap (TypeData typeData)
\r
1756 XmlTypeMapping map = new XmlTypeMapping (typeData.XmlType, XmlSchema.Namespace, typeData, typeData.XmlType, XmlSchema.Namespace);
\r
1757 map.IncludeInSchema = false;
\r
1758 map.ObjectMap = new ClassMap ();
\r
1759 dataMappedTypes [typeData] = map;
\r
1763 void ImportAllObjectTypes ()
\r
1765 // All complex types are subtypes of anyType, so all of them
\r
1766 // must also be imported
\r
1768 anyTypeImported = true;
\r
1769 foreach (XmlSchema schema in schemas) {
\r
1770 foreach (XmlSchemaObject sob in schema.Items)
\r
1772 XmlSchemaComplexType sct = sob as XmlSchemaComplexType;
\r
1774 ImportType (new XmlQualifiedName (sct.Name, schema.TargetNamespace), sct, null);
\r
1780 XmlTypeMapping GetRegisteredTypeMapping (XmlQualifiedName typeQName)
\r
1782 return (XmlTypeMapping) mappedTypes [typeQName];
\r
1785 XmlSchemaParticle GetRefGroupParticle (XmlSchemaGroupRef refGroup)
\r
1787 XmlSchemaGroup grp = (XmlSchemaGroup) schemas.Find (refGroup.RefName, typeof (XmlSchemaGroup));
\r
1788 return grp.Particle;
\r
1791 XmlSchemaElement FindRefElement (XmlSchemaElement elem)
\r
1793 XmlSchemaElement refelem = (XmlSchemaElement) schemas.Find (elem.RefName, typeof(XmlSchemaElement));
\r
1794 if (refelem != null) return refelem;
\r
1796 if (IsPrimitiveTypeNamespace (elem.RefName.Namespace))
\r
1798 if (anyElement != null) return anyElement;
\r
1799 anyElement = new XmlSchemaElement ();
\r
1800 anyElement.Name = "any";
\r
1801 anyElement.SchemaTypeName = anyType;
\r
1802 return anyElement;
\r
1807 XmlSchemaAttribute FindRefAttribute (XmlQualifiedName refName)
\r
1809 if (refName.Namespace == XmlNamespace)
\r
1811 XmlSchemaAttribute at = new XmlSchemaAttribute ();
\r
1812 at.Name = refName.Name;
\r
1813 at.SchemaTypeName = new XmlQualifiedName ("string",XmlSchema.Namespace);
\r
1816 return (XmlSchemaAttribute) schemas.Find (refName, typeof(XmlSchemaAttribute));
\r
1819 XmlSchemaAttributeGroup FindRefAttributeGroup (XmlQualifiedName refName)
\r
1821 XmlSchemaAttributeGroup grp = (XmlSchemaAttributeGroup) schemas.Find (refName, typeof(XmlSchemaAttributeGroup));
\r
1822 foreach (XmlSchemaObject at in grp.Attributes)
\r
1824 if (at is XmlSchemaAttributeGroupRef && ((XmlSchemaAttributeGroupRef)at).RefName == refName)
\r
1825 throw new InvalidOperationException ("Cannot import attribute group '" + refName.Name + "' from namespace '" + refName.Namespace + "'. Redefine not supported");
\r
1831 XmlTypeMapping ReflectType (Type type)
\r
1833 TypeData typeData = TypeTranslator.GetTypeData (type);
\r
1834 return ReflectType (typeData, (string) null);
\r
1837 XmlTypeMapping ReflectType (TypeData typeData, string ns)
\r
1839 if (!encodedFormat)
\r
1841 if (auxXmlRefImporter == null) auxXmlRefImporter = new XmlReflectionImporter ();
\r
1842 return auxXmlRefImporter.ImportTypeMapping (typeData, ns);
\r
1846 if (auxSoapRefImporter == null) auxSoapRefImporter = new SoapReflectionImporter ();
\r
1847 return auxSoapRefImporter.ImportTypeMapping (typeData, ns);
\r
1852 string GetDocumentation (XmlSchemaAnnotated elem)
\r
1855 XmlSchemaAnnotation anot = elem.Annotation;
\r
1856 if (anot == null || anot.Items == null) return null;
\r
1858 foreach (object ob in anot.Items)
\r
1860 XmlSchemaDocumentation doc = ob as XmlSchemaDocumentation;
\r
1861 if (doc != null && doc.Markup != null && doc.Markup.Length > 0) {
\r
1862 if (res != string.Empty) res += "\n";
\r
1863 foreach (XmlNode node in doc.Markup)
\r
1864 res += node.Value;
\r
1870 bool IsPrimitiveTypeNamespace (string ns)
\r
1872 return (ns == XmlSchema.Namespace) || (encodedFormat && ns == XmlSerializer.EncodingNamespace);
\r
1875 #endregion // Methods
\r