2 // System.Xml.Serialization.XmlReflectionImporter
5 // Tim Coleman (tim@timcoleman.com)
6 // Erik LeBel (eriklebel@yahoo.ca)
7 // Lluis Sanchez Gual (lluis@ximian.com)
9 // Copyright (C) Tim Coleman, 2002
10 // (C) 2003 Erik LeBel
13 using System.Reflection;
14 using System.Collections;
16 namespace System.Xml.Serialization {
17 public class XmlReflectionImporter {
19 string initialDefaultNamespace;
20 XmlAttributeOverrides attributeOverrides;
21 ArrayList includedTypes;
22 ReflectionHelper helper = new ReflectionHelper();
23 int arrayChoiceCount = 1;
24 ArrayList relatedMaps = new ArrayList ();
25 bool allowPrivateTypes = false;
27 static readonly string errSimple = "Cannot serialize object of type '{0}'. Base " +
28 "type '{1}' has simpleContent and can be only extended by adding XmlAttribute " +
29 "elements. Please consider changing XmlTextMember of the base class to string array";
33 public XmlReflectionImporter ()
38 public XmlReflectionImporter (string defaultNamespace)
39 : this (null, defaultNamespace)
43 public XmlReflectionImporter (XmlAttributeOverrides attributeOverrides)
44 : this (attributeOverrides, null)
48 public XmlReflectionImporter (XmlAttributeOverrides attributeOverrides, string defaultNamespace)
50 if (defaultNamespace == null)
51 this.initialDefaultNamespace = String.Empty;
53 this.initialDefaultNamespace = defaultNamespace;
55 if (attributeOverrides == null)
56 this.attributeOverrides = new XmlAttributeOverrides();
58 this.attributeOverrides = attributeOverrides;
63 helper = new ReflectionHelper();
67 internal bool AllowPrivateTypes
69 get { return allowPrivateTypes; }
70 set { allowPrivateTypes = value; }
73 #endregion // Constructors
77 public XmlMembersMapping ImportMembersMapping (string elementName,
79 XmlReflectionMember [] members,
80 bool hasWrapperElement)
83 XmlMemberMapping[] mapping = new XmlMemberMapping[members.Length];
84 for (int n=0; n<members.Length; n++)
86 XmlTypeMapMember mapMem = CreateMapMember (members[n], ns);
87 mapping[n] = new XmlMemberMapping (members[n].MemberName, ns, mapMem, false);
89 XmlMembersMapping mps = new XmlMembersMapping (elementName, ns, hasWrapperElement, false, mapping);
90 mps.RelatedMaps = relatedMaps;
91 mps.Format = SerializationFormat.Literal;
95 public XmlTypeMapping ImportTypeMapping (Type type)
97 return ImportTypeMapping (type, null, null);
100 public XmlTypeMapping ImportTypeMapping (Type type, string defaultNamespace)
102 return ImportTypeMapping (type, null, defaultNamespace);
105 public XmlTypeMapping ImportTypeMapping (Type type, XmlRootAttribute group)
107 return ImportTypeMapping (type, group, null);
110 public XmlTypeMapping ImportTypeMapping (Type type, XmlRootAttribute root, string defaultNamespace)
113 throw new ArgumentNullException ("type");
115 if (type == typeof (void))
116 throw new InvalidOperationException ("Type " + type.Name + " may not be serialized.");
118 if (defaultNamespace == null) defaultNamespace = initialDefaultNamespace;
119 if (defaultNamespace == null) defaultNamespace = string.Empty;
123 switch (TypeTranslator.GetTypeData(type).SchemaType)
125 case SchemaTypes.Class: map = ImportClassMapping (type, root, defaultNamespace); break;
126 case SchemaTypes.Array: map = ImportListMapping (type, root, defaultNamespace, null, 0); break;
127 case SchemaTypes.XmlNode: map = ImportXmlNodeMapping (type, root, defaultNamespace); break;
128 case SchemaTypes.Primitive: map = ImportPrimitiveMapping (type, root, defaultNamespace); break;
129 case SchemaTypes.Enum: map = ImportEnumMapping (type, root, defaultNamespace); break;
130 case SchemaTypes.XmlSerializable: map = ImportXmlSerializableMapping (type, root, defaultNamespace); break;
131 default: throw new NotSupportedException ("Type " + type.FullName + " not supported for XML stialization");
134 map.RelatedMaps = relatedMaps;
135 map.Format = SerializationFormat.Literal;
139 XmlTypeMapping CreateTypeMapping (TypeData typeData, XmlRootAttribute root, string defaultXmlType, string defaultNamespace)
141 string rootNamespace = defaultNamespace;
142 string typeNamespace = null;
145 bool includeInSchema = true;
146 XmlAttributes atts = null;
147 if (defaultXmlType == null) defaultXmlType = typeData.XmlType;
149 if (!typeData.IsListType)
151 if (attributeOverrides != null)
152 atts = attributeOverrides[typeData.Type];
154 if (atts != null && typeData.SchemaType == SchemaTypes.Primitive)
155 throw new InvalidOperationException ("XmlRoot and XmlType attributes may not be specified for the type " + typeData.FullTypeName);
159 atts = new XmlAttributes (typeData.Type);
161 if (atts.XmlRoot != null && root == null)
164 if (atts.XmlType != null)
166 if (atts.XmlType.Namespace != null && atts.XmlType.Namespace != string.Empty && typeData.SchemaType != SchemaTypes.Enum)
167 typeNamespace = atts.XmlType.Namespace;
169 if (atts.XmlType.TypeName != null && atts.XmlType.TypeName != string.Empty)
170 defaultXmlType = atts.XmlType.TypeName;
172 includeInSchema = atts.XmlType.IncludeInSchema;
175 elementName = defaultXmlType;
179 if (root.ElementName != null && root.ElementName != String.Empty)
180 elementName = root.ElementName;
181 if (root.Namespace != null && root.Namespace != String.Empty)
182 rootNamespace = root.Namespace;
185 if (rootNamespace == null) rootNamespace = "";
186 if (typeNamespace == null || typeNamespace.Length == 0) typeNamespace = rootNamespace;
188 XmlTypeMapping map = new XmlTypeMapping (elementName, rootNamespace, typeData, defaultXmlType, typeNamespace);
189 map.IncludeInSchema = includeInSchema;
190 relatedMaps.Add (map);
195 XmlTypeMapping ImportClassMapping (Type type, XmlRootAttribute root, string defaultNamespace)
197 TypeData typeData = TypeTranslator.GetTypeData (type);
198 XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
199 if (map != null) return map;
201 if (!allowPrivateTypes)
202 ReflectionHelper.CheckSerializableType (type);
204 map = CreateTypeMapping (typeData, root, null, defaultNamespace);
205 helper.RegisterClrType (map, type, map.XmlTypeNamespace);
206 helper.RegisterSchemaType (map, map.XmlType, map.XmlTypeNamespace);
210 ClassMap classMap = new ClassMap ();
211 map.ObjectMap = classMap;
215 ICollection members = GetReflectionMembers (type);
216 foreach (XmlReflectionMember rmember in members)
218 if (rmember.XmlAttributes.XmlIgnore) continue;
219 XmlTypeMapMember mem = CreateMapMember (rmember, map.XmlTypeNamespace);
220 mem.CheckOptionalValueType (type);
221 classMap.AddMember (mem);
224 // catch (Exception ex) {
225 // throw helper.CreateError (map, ex.Message);
228 ImportIncludedTypes (type, defaultNamespace);
230 // Import extra classes
232 if (type == typeof (object) && includedTypes != null)
234 foreach (Type intype in includedTypes)
235 map.DerivedTypes.Add (ImportTypeMapping (intype, defaultNamespace));
238 // Register inheritance relations
240 if (type.BaseType != null)
242 XmlTypeMapping bmap = ImportClassMapping (type.BaseType, root, defaultNamespace);
244 if (type.BaseType != typeof (object))
247 // At this point, derived classes of this map must be already registered
249 bmap.DerivedTypes.Add (map);
250 bmap.DerivedTypes.AddRange (map.DerivedTypes);
252 if (((ClassMap)bmap.ObjectMap).HasSimpleContent && classMap.ElementMembers != null && classMap.ElementMembers.Count != 1)
253 throw new InvalidOperationException (String.Format (errSimple, map.TypeData.TypeName, map.BaseMap.TypeData.TypeName));
259 string GetTypeNamespace (TypeData typeData, XmlRootAttribute root, string defaultNamespace)
261 string typeNamespace = null;
263 XmlAttributes atts = null;
264 if (!typeData.IsListType)
266 if (attributeOverrides != null)
267 atts = attributeOverrides[typeData.Type];
271 atts = new XmlAttributes (typeData.Type);
273 if (atts.XmlType != null)
275 if (atts.XmlType.Namespace != null && atts.XmlType.Namespace.Length != 0 && typeData.SchemaType != SchemaTypes.Enum)
276 typeNamespace = atts.XmlType.Namespace;
279 if (typeNamespace != null && typeNamespace.Length != 0) return typeNamespace;
281 if (atts.XmlRoot != null && root == null)
286 if (root.Namespace != null && root.Namespace.Length != 0)
287 return root.Namespace;
290 if (defaultNamespace == null) return "";
291 else return defaultNamespace;
294 XmlTypeMapping ImportListMapping (Type type, XmlRootAttribute root, string defaultNamespace, XmlAttributes atts, int nestingLevel)
296 TypeData typeData = TypeTranslator.GetTypeData (type);
297 ListMap obmap = new ListMap ();
299 if (!allowPrivateTypes)
300 ReflectionHelper.CheckSerializableType (type);
302 if (atts == null) atts = new XmlAttributes();
303 Type itemType = typeData.ListItemType;
305 // warning: byte[][] should not be considered multiarray
306 bool isMultiArray = (type.IsArray && (TypeTranslator.GetTypeData(itemType).SchemaType == SchemaTypes.Array) && itemType.IsArray);
308 XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
310 foreach (XmlArrayItemAttribute att in atts.XmlArrayItems)
312 if (att.NestingLevel != nestingLevel) continue;
313 Type elemType = (att.Type != null) ? att.Type : itemType;
314 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (null, TypeTranslator.GetTypeData(elemType, att.DataType));
315 elem.Namespace = att.Namespace != null ? att.Namespace : defaultNamespace;
316 if (elem.Namespace == null) elem.Namespace = "";
317 elem.Form = att.Form;
318 elem.IsNullable = att.IsNullable && CanBeNull (elem.TypeData);
319 elem.NestingLevel = att.NestingLevel;
322 elem.MappedType = ImportListMapping (elemType, null, elem.Namespace, atts, nestingLevel + 1);
323 else if (elem.TypeData.IsComplexType)
324 elem.MappedType = ImportTypeMapping (elemType, null, elem.Namespace);
326 if (att.ElementName != null) elem.ElementName = att.ElementName;
327 else if (elem.MappedType != null) elem.ElementName = elem.MappedType.ElementName;
328 else elem.ElementName = TypeTranslator.GetTypeData(elemType).XmlType;
335 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (null, TypeTranslator.GetTypeData (itemType));
337 elem.MappedType = ImportListMapping (itemType, null, defaultNamespace, atts, nestingLevel + 1);
338 else if (elem.TypeData.IsComplexType)
339 elem.MappedType = ImportTypeMapping (itemType, null, defaultNamespace);
341 if (elem.MappedType != null) elem.ElementName = elem.MappedType.XmlType;
342 else elem.ElementName = TypeTranslator.GetTypeData(itemType).XmlType ;
344 elem.Namespace = (defaultNamespace != null) ? defaultNamespace : "";
345 elem.IsNullable = CanBeNull (elem.TypeData);
349 obmap.ItemInfo = list;
351 // If there can be different element names (types) in the array, then its name cannot
352 // be "ArrayOfXXX" it must be something like ArrayOfChoiceNNN
356 baseName = "ArrayOfChoice" + (arrayChoiceCount++);
359 XmlTypeMapElementInfo elem = ((XmlTypeMapElementInfo)list[0]);
360 if (elem.MappedType != null) baseName = TypeTranslator.GetArrayName (elem.MappedType.XmlType);
361 else baseName = TypeTranslator.GetArrayName (elem.ElementName);
364 // Avoid name colisions
367 string name = baseName;
370 XmlTypeMapping foundMap = helper.GetRegisteredSchemaType (name, defaultNamespace);
371 if (foundMap == null) nameCount = -1;
372 else if (obmap.Equals (foundMap.ObjectMap) && typeData.Type == foundMap.TypeData.Type) return foundMap;
373 else name = baseName + (nameCount++);
375 while (nameCount != -1);
377 XmlTypeMapping map = CreateTypeMapping (typeData, root, name, defaultNamespace);
378 map.ObjectMap = obmap;
380 // Register any of the including types as a derived class of object
381 XmlIncludeAttribute[] includes = (XmlIncludeAttribute[])type.GetCustomAttributes (typeof (XmlIncludeAttribute), false);
383 XmlTypeMapping objectMapping = ImportTypeMapping (typeof(object));
384 for (int i = 0; i < includes.Length; i++)
386 Type includedType = includes[i].Type;
387 objectMapping.DerivedTypes.Add(ImportTypeMapping (includedType, null, defaultNamespace));
390 // Register this map as a derived class of object
392 helper.RegisterSchemaType (map, name, defaultNamespace);
393 ImportTypeMapping (typeof(object)).DerivedTypes.Add (map);
398 XmlTypeMapping ImportXmlNodeMapping (Type type, XmlRootAttribute root, string defaultNamespace)
400 XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (TypeTranslator.GetTypeData (type), root, defaultNamespace));
401 if (map != null) return map;
403 // Registers the maps for XmlNode and XmlElement
405 XmlTypeMapping nodeMap = CreateTypeMapping (TypeTranslator.GetTypeData (typeof(XmlNode)), root, null, defaultNamespace);
406 helper.RegisterClrType (nodeMap, typeof(XmlNode), nodeMap.XmlTypeNamespace);
408 XmlTypeMapping elemMap = CreateTypeMapping (TypeTranslator.GetTypeData (typeof(XmlElement)), root, null, defaultNamespace);
409 helper.RegisterClrType (elemMap, typeof(XmlElement), elemMap.XmlTypeNamespace);
411 XmlTypeMapping textMap = CreateTypeMapping (TypeTranslator.GetTypeData (typeof(XmlText)), root, null, defaultNamespace);
412 helper.RegisterClrType (elemMap, typeof(XmlText), textMap.XmlTypeNamespace);
414 XmlTypeMapping obmap = ImportTypeMapping (typeof(object));
415 obmap.DerivedTypes.Add (nodeMap);
416 obmap.DerivedTypes.Add (elemMap);
417 obmap.DerivedTypes.Add (textMap);
418 nodeMap.DerivedTypes.Add (elemMap);
419 nodeMap.DerivedTypes.Add (textMap);
421 return helper.GetRegisteredClrType (type, GetTypeNamespace (TypeTranslator.GetTypeData (type), root, defaultNamespace));
424 XmlTypeMapping ImportPrimitiveMapping (Type type, XmlRootAttribute root, string defaultNamespace)
426 TypeData typeData = TypeTranslator.GetTypeData (type);
427 XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
428 if (map != null) return map;
429 map = CreateTypeMapping (typeData, root, null, defaultNamespace);
430 helper.RegisterClrType (map, type, map.XmlTypeNamespace);
434 XmlTypeMapping ImportEnumMapping (Type type, XmlRootAttribute root, string defaultNamespace)
436 TypeData typeData = TypeTranslator.GetTypeData (type);
437 XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
438 if (map != null) return map;
439 map = CreateTypeMapping (typeData, root, null, defaultNamespace);
440 helper.RegisterClrType (map, type, map.XmlTypeNamespace);
442 string [] names = Enum.GetNames (type);
443 ArrayList members = new ArrayList();
444 foreach (string name in names)
446 MemberInfo[] mem = type.GetMember (name);
447 string xmlName = null;
448 object[] atts = mem[0].GetCustomAttributes (typeof(XmlIgnoreAttribute), false);
449 if (atts.Length > 0) continue;
450 atts = mem[0].GetCustomAttributes (typeof(XmlEnumAttribute), false);
451 if (atts.Length > 0) xmlName = ((XmlEnumAttribute)atts[0]).Name;
452 if (xmlName == null) xmlName = name;
453 members.Add (new EnumMap.EnumMapMember (xmlName, name));
456 bool isFlags = type.GetCustomAttributes (typeof(FlagsAttribute),false).Length > 0;
457 map.ObjectMap = new EnumMap ((EnumMap.EnumMapMember[])members.ToArray (typeof(EnumMap.EnumMapMember)), isFlags);
458 ImportTypeMapping (typeof(object)).DerivedTypes.Add (map);
462 XmlTypeMapping ImportXmlSerializableMapping (Type type, XmlRootAttribute root, string defaultNamespace)
464 TypeData typeData = TypeTranslator.GetTypeData (type);
465 XmlTypeMapping map = helper.GetRegisteredClrType (type, GetTypeNamespace (typeData, root, defaultNamespace));
466 if (map != null) return map;
467 map = CreateTypeMapping (typeData, root, null, defaultNamespace);
468 helper.RegisterClrType (map, type, map.XmlTypeNamespace);
472 void ImportIncludedTypes (Type type, string defaultNamespace)
474 XmlIncludeAttribute[] includes = (XmlIncludeAttribute[])type.GetCustomAttributes (typeof (XmlIncludeAttribute), false);
475 for (int n=0; n<includes.Length; n++)
477 Type includedType = includes[n].Type;
478 ImportTypeMapping (includedType, null, defaultNamespace);
482 public ICollection GetReflectionMembers (Type type)
484 ArrayList members = new ArrayList();
485 PropertyInfo[] properties = type.GetProperties (BindingFlags.Instance | BindingFlags.Public);
486 foreach (PropertyInfo prop in properties)
488 if (!prop.CanRead) continue;
489 if (!prop.CanWrite && TypeTranslator.GetTypeData (prop.PropertyType).SchemaType != SchemaTypes.Array)
491 if (prop.GetIndexParameters().Length > 0) continue;
493 XmlAttributes atts = attributeOverrides[type, prop.Name];
494 if (atts == null) atts = new XmlAttributes (prop);
495 if (atts.XmlIgnore) continue;
496 XmlReflectionMember member = new XmlReflectionMember(prop.Name, prop.PropertyType, atts);
497 members.Add (member);
500 FieldInfo[] fields = type.GetFields (BindingFlags.Instance | BindingFlags.Public);
501 foreach (FieldInfo field in fields)
503 XmlAttributes atts = attributeOverrides[type, field.Name];
504 if (atts == null) atts = new XmlAttributes (field);
505 if (atts.XmlIgnore) continue;
506 XmlReflectionMember member = new XmlReflectionMember(field.Name, field.FieldType, atts);
507 members.Add (member);
512 private XmlTypeMapMember CreateMapMember (XmlReflectionMember rmember, string defaultNamespace)
514 XmlTypeMapMember mapMember;
515 XmlAttributes atts = rmember.XmlAttributes;
516 TypeData typeData = TypeTranslator.GetTypeData (rmember.MemberType);
518 if (atts.XmlAnyAttribute != null)
520 if ( (rmember.MemberType.FullName == "System.Xml.XmlAttribute[]") ||
521 (rmember.MemberType.FullName == "System.Xml.XmlNode[]") )
523 mapMember = new XmlTypeMapMemberAnyAttribute();
526 throw new InvalidOperationException ("XmlAnyAttributeAttribute can only be applied to members of type XmlAttribute[] or XmlNode[]");
528 else if (atts.XmlAnyElements != null && atts.XmlAnyElements.Count > 0)
530 if ( (rmember.MemberType.FullName == "System.Xml.XmlElement[]") ||
531 (rmember.MemberType.FullName == "System.Xml.XmlNode[]") ||
532 (rmember.MemberType.FullName == "System.Xml.XmlElement"))
534 XmlTypeMapMemberAnyElement member = new XmlTypeMapMemberAnyElement();
535 member.ElementInfo = ImportAnyElementInfo (defaultNamespace, rmember.MemberType, member, atts);
539 throw new InvalidOperationException ("XmlAnyElementAttribute can only be applied to members of type XmlElement, XmlElement[] or XmlNode[]");
543 XmlTypeMapMemberNamespaces mapNamespaces = new XmlTypeMapMemberNamespaces ();
544 mapMember = mapNamespaces;
546 else if (atts.XmlAttribute != null)
550 if (atts.XmlElements != null && atts.XmlElements.Count > 0)
551 throw new Exception ("XmlAttributeAttribute and XmlElementAttribute cannot be applied to the same member");
553 XmlTypeMapMemberAttribute mapAttribute = new XmlTypeMapMemberAttribute ();
554 if (atts.XmlAttribute.AttributeName == null)
555 mapAttribute.AttributeName = rmember.MemberName;
557 mapAttribute.AttributeName = atts.XmlAttribute.AttributeName;
559 mapAttribute.Form = atts.XmlAttribute.Form;
560 mapAttribute.Namespace = (atts.XmlAttribute.Namespace != null) ? atts.XmlAttribute.Namespace : "";
561 if (typeData.IsComplexType)
562 mapAttribute.MappedType = ImportTypeMapping (typeData.Type, null, mapAttribute.Namespace);
564 typeData = TypeTranslator.GetTypeData(rmember.MemberType, atts.XmlAttribute.DataType);
565 mapMember = mapAttribute;
567 else if (typeData.SchemaType == SchemaTypes.Array)
569 // If the member has a single XmlElementAttribute and the type is the type of the member,
570 // then it is not a flat list
572 if (atts.XmlElements.Count > 1 ||
573 (atts.XmlElements.Count == 1 && atts.XmlElements[0].Type != typeData.Type) ||
574 (atts.XmlText != null))
578 // TODO: check that it does not have XmlArrayAttribute
579 XmlTypeMapMemberFlatList member = new XmlTypeMapMemberFlatList ();
580 member.ListMap = new ListMap ();
581 member.ListMap.ItemInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, typeData.ListItemType, member, atts);
582 member.ElementInfo = member.ListMap.ItemInfo;
589 XmlTypeMapMemberList member = new XmlTypeMapMemberList ();
591 // Creates an ElementInfo that identifies the array instance.
592 member.ElementInfo = new XmlTypeMapElementInfoList();
593 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, typeData);
594 elem.ElementName = (atts.XmlArray != null && atts.XmlArray.ElementName != null) ? atts.XmlArray.ElementName : rmember.MemberName;
595 elem.Namespace = (atts.XmlArray != null && atts.XmlArray.Namespace != null) ? atts.XmlArray.Namespace : defaultNamespace;
596 elem.MappedType = ImportListMapping (rmember.MemberType, null, elem.Namespace, atts, 0);
597 elem.IsNullable = (atts.XmlArray != null) ? atts.XmlArray.IsNullable : false;
598 member.ElementInfo.Add (elem);
606 XmlTypeMapMemberElement member = new XmlTypeMapMemberElement ();
607 member.ElementInfo = ImportElementInfo (rmember.MemberName, defaultNamespace, rmember.MemberType, member, atts);
611 mapMember.DefaultValue = atts.XmlDefaultValue;
612 mapMember.TypeData = typeData;
613 mapMember.Name = rmember.MemberName;
617 XmlTypeMapElementInfoList ImportElementInfo (string defaultName, string defaultNamespace, Type defaultType, XmlTypeMapMemberElement member, XmlAttributes atts)
619 XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
621 ImportTextElementInfo (list, defaultType, member, atts);
623 if (atts.XmlElements.Count == 0 && list.Count == 0)
625 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(defaultType));
626 elem.ElementName = defaultName;
627 elem.Namespace = defaultNamespace;
628 if (elem.TypeData.IsComplexType)
629 elem.MappedType = ImportTypeMapping (defaultType, null, defaultNamespace);
633 bool multiType = (atts.XmlElements.Count > 1);
634 foreach (XmlElementAttribute att in atts.XmlElements)
636 Type elemType = (att.Type != null) ? att.Type : defaultType;
637 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(elemType, att.DataType));
638 elem.ElementName = (att.ElementName != null) ? att.ElementName : defaultName;
639 elem.Namespace = (att.Namespace != null) ? att.Namespace : defaultNamespace;
640 elem.Form = att.Form;
641 elem.IsNullable = att.IsNullable;
643 if (elem.IsNullable && elem.TypeData.IsValueType)
644 throw new InvalidOperationException ("IsNullable may not be 'true' for value type " + elem.TypeData.FullTypeName);
646 if (elem.TypeData.IsComplexType)
648 if (att.DataType != null) throw new InvalidOperationException ("'" + att.DataType + "' is an invalid value for the XmlElementAttribute.DateTime property. The property may only be specified for primitive types.");
649 elem.MappedType = ImportTypeMapping (elemType, null, elem.Namespace);
652 if (att.ElementName != null)
653 elem.ElementName = att.ElementName;
654 else if (multiType) {
655 if (elem.MappedType != null) elem.ElementName = elem.MappedType.ElementName;
656 else elem.ElementName = TypeTranslator.GetTypeData(elemType).XmlType;
659 elem.ElementName = defaultName;
666 XmlTypeMapElementInfoList ImportAnyElementInfo (string defaultNamespace, Type defaultType, XmlTypeMapMemberElement member, XmlAttributes atts)
668 XmlTypeMapElementInfoList list = new XmlTypeMapElementInfoList();
670 ImportTextElementInfo (list, defaultType, member, atts);
672 foreach (XmlAnyElementAttribute att in atts.XmlAnyElements)
674 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(typeof(XmlElement)));
675 if (att.Name != null && att.Name != string.Empty) elem.ElementName = att.Name;
676 else elem.IsUnnamedAnyElement = true;
677 elem.Namespace = (att.Namespace != null) ? att.Namespace : "";
683 void ImportTextElementInfo (XmlTypeMapElementInfoList list, Type defaultType, XmlTypeMapMemberElement member, XmlAttributes atts)
685 if (atts.XmlText != null)
687 member.IsXmlTextCollector = true;
688 if (atts.XmlText.Type != null) defaultType = atts.XmlText.Type;
689 if (defaultType == typeof(XmlNode)) defaultType = typeof(XmlText); // Nodes must be text nodes
691 XmlTypeMapElementInfo elem = new XmlTypeMapElementInfo (member, TypeTranslator.GetTypeData(defaultType, atts.XmlText.DataType));
693 if (elem.TypeData.SchemaType != SchemaTypes.Primitive &&
694 elem.TypeData.SchemaType != SchemaTypes.Enum &&
695 elem.TypeData.SchemaType != SchemaTypes.XmlNode &&
696 !(elem.TypeData.SchemaType == SchemaTypes.Array && elem.TypeData.ListItemTypeData.SchemaType == SchemaTypes.XmlNode)
698 throw new InvalidOperationException ("XmlText cannot be used to encode complex types");
700 elem.IsTextElement = true;
701 elem.WrappedElement = false;
706 bool CanBeNull (TypeData type)
708 return (type.SchemaType != SchemaTypes.Primitive || type.Type == typeof (string));
711 public void IncludeType (Type type)
714 throw new ArgumentNullException ("type");
716 if (includedTypes == null) includedTypes = new ArrayList ();
717 includedTypes.Add (type);
720 #endregion // Methods