5 // John Donagher (john@webmeta.com)
6 // Ajay kumar Dwivedi (adwiv@yahoo.com)
7 // (C) 2002 John Donagher, Ajay kumar Dwivedi
10 using System.Xml.Serialization;
\r
14 using System.Collections;
\r
15 using System.Reflection;
\r
17 namespace System.Xml.Serialization
\r
20 /// Summary description for XmlSerializer.
\r
22 public class XmlSerializer
\r
25 private XmlAttributeOverrides overrides;
\r
26 private Type[] extraTypes;
\r
27 private XmlRootAttribute rootAttribute;
\r
28 private string defaultNamespace;
\r
29 private static Hashtable typeTable;
\r
30 private bool useOrder;
\r
32 private bool isNullable;
\r
34 public bool UseOrder
\r
36 get{ return useOrder; }
\r
37 set{ useOrder = value; }
\r
40 #region constructors
\r
41 protected XmlSerializer ()
\r
45 public XmlSerializer (Type type)
\r
46 : this(type, null, null, null, null)
\r
50 public XmlSerializer (XmlTypeMapping xmltypemapping)
\r
53 public XmlSerializer (Type type, string defaultNamespace)
\r
54 : this(type, null, null, null, defaultNamespace)
\r
57 public XmlSerializer (Type type, Type[] extraTypes)
\r
58 : this(type, null, extraTypes, null, null)
\r
61 public XmlSerializer (Type type, XmlAttributeOverrides overrides)
\r
62 : this(type, overrides, null, null, null)
\r
65 public XmlSerializer (Type type, XmlRootAttribute root)
\r
66 : this(type, null, null, root, null)
\r
69 internal XmlSerializer(Hashtable typeTable)
\r
71 typeTable = typeTable;
\r
74 public XmlSerializer (Type type, XmlAttributeOverrides overrides, Type[] extraTypes, XmlRootAttribute root, string defaultNamespace)
\r
77 throw new ArgumentNullException("type", "XmlSerializer can't be consturcted with a null type");
\r
80 this.overrides = overrides;
\r
82 this.extraTypes = (extraTypes == null ? new Type[0] : extraTypes);
\r
84 this.rootAttribute = root;
\r
86 this.defaultNamespace = defaultNamespace;
\r
88 if(typeTable == null)
\r
89 typeTable = new Hashtable();
\r
91 FillTypeTable(type);
\r
96 public event XmlAttributeEventHandler UnknownAttribute;
\r
98 public event XmlElementEventHandler UnknownElement;
\r
100 public event XmlNodeEventHandler UnknownNode;
\r
102 public event UnreferencedObjectEventHandler UnreferencedObject;
\r
104 #region Deserialize
\r
106 public virtual bool CanDeserialize (XmlReader xmlReader)
\r
108 throw new NotImplementedException ();
\r
111 public object Deserialize (Stream stream)
\r
113 throw new NotImplementedException ();
\r
116 public object Deserialize (TextReader textReader)
\r
118 throw new NotImplementedException ();
\r
121 public object Deserialize (XmlReader xmlReader)
\r
123 throw new NotImplementedException ();
\r
126 #region Serialize Delegates
\r
127 public void Serialize (Stream stream, object o)
\r
129 XmlTextWriter xmlWriter = new XmlTextWriter(stream, System.Text.Encoding.Default);
\r
130 xmlWriter.Formatting = Formatting.Indented;
\r
131 Serialize(xmlWriter, o, null);
\r
134 public void Serialize (TextWriter textWriter, object o)
\r
136 XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
\r
137 xmlWriter.Formatting = Formatting.Indented;
\r
138 Serialize(xmlWriter, o, null);
\r
141 public void Serialize (XmlWriter xmlWriter, object o)
\r
143 Serialize(xmlWriter, o);
\r
146 public void Serialize (Stream stream, object o, XmlSerializerNamespaces namespaces)
\r
148 XmlTextWriter xmlWriter = new XmlTextWriter(stream, System.Text.Encoding.Default);
\r
149 xmlWriter.Formatting = Formatting.Indented;
\r
150 Serialize(xmlWriter, o, namespaces);
\r
153 public void Serialize (TextWriter textWriter, object o, XmlSerializerNamespaces namespaces)
\r
155 XmlTextWriter xmlWriter = new XmlTextWriter(textWriter);
\r
156 xmlWriter.Formatting = Formatting.Indented;
\r
157 Serialize(xmlWriter, o, namespaces);
\r
161 public void Serialize (XmlWriter writer, object o, XmlSerializerNamespaces namespaces)
\r
163 if(namespaces == null)
\r
165 namespaces = new XmlSerializerNamespaces();
\r
167 if(namespaces.Count == 0)
\r
169 namespaces.Add("xsd", System.Xml.Schema.XmlSchema.Namespace);
\r
170 namespaces.Add("xsi", System.Xml.Schema.XmlSchema.InstanceNamespace);
\r
173 Type objType = o.GetType();
\r
174 string rootName = objType.Name;
\r
175 string rootNs = null;
\r
176 XmlSerializerNamespaces nss = new XmlSerializerNamespaces();
\r
177 XmlQualifiedName[] qnames;
\r
179 writer.WriteStartDocument();
\r
181 object[] memberObj = (object[])typeTable[objType];
\r
182 if(memberObj == null)
\r
183 throw new Exception("Unknown Type "+objType+" encounterd during Serialization");
\r
184 Hashtable memberTable = (Hashtable)memberObj[0];
\r
186 XmlAttributes attrs = (XmlAttributes)memberTable[""];
\r
187 //If we have been passed an XmlRoot, set it on the base class
\r
188 if(rootAttribute != null)
\r
189 attrs.XmlRoot = rootAttribute;
\r
191 if(attrs.XmlRoot != null)
\r
193 isNullable = attrs.XmlRoot.IsNullable;
\r
194 if(attrs.XmlRoot.ElementName != null)
\r
195 rootName = attrs.XmlRoot.ElementName;
\r
196 rootNs = attrs.XmlRoot.Namespace;
\r
199 //XMLNS attributes in the Root
\r
200 XmlAttributes XnsAttrs = (XmlAttributes)((object[])typeTable[objType])[1];
\r
201 if(XnsAttrs != null)
\r
203 MemberInfo member = XnsAttrs.MemberInfo;
\r
204 FieldInfo fInfo = member as FieldInfo;
\r
205 PropertyInfo propInfo = member as PropertyInfo;
\r
206 XmlSerializerNamespaces xns;
\r
208 xns = (XmlSerializerNamespaces) fInfo.GetValue(o);
\r
210 xns = (XmlSerializerNamespaces) propInfo.GetValue(o,null);
\r
212 qnames = xns.ToArray();
\r
213 foreach(XmlQualifiedName qname in qnames)
\r
215 nss.Add(qname.Name, qname.Namespace);
\r
218 //XmlNs from the namespaces passed
\r
219 qnames = namespaces.ToArray();
\r
220 foreach(XmlQualifiedName qname in qnames)
\r
222 if(writer.LookupPrefix(qname.Namespace) != qname.Name)
\r
224 nss.Add(qname.Name, qname.Namespace);
\r
228 if(namespaces.GetPrefix(rootNs) != null)
\r
229 writer.WriteStartElement(namespaces.GetPrefix(rootNs),rootName, rootNs);
\r
231 qnames = nss.ToArray();
\r
232 foreach(XmlQualifiedName qname in qnames)
\r
234 if(writer.LookupPrefix(qname.Namespace) != qname.Name)
\r
236 writer.WriteAttributeString("xmlns", qname.Name, null, qname.Namespace);
\r
240 SerializeMembers(writer, o, true);//, namespaces);
\r
241 writer.WriteEndElement();
\r
244 private void SerializeMembers ( XmlWriter writer, object o, bool isRoot)
\r
246 Type objType = o.GetType();
\r
247 XmlAttributes XnsAttrs = (XmlAttributes)((object[])typeTable[objType])[1];
\r
248 ArrayList attrList = (ArrayList)((object[])typeTable[objType])[2];
\r
249 ArrayList elemList = (ArrayList)((object[])typeTable[objType])[3];
\r
251 if(!isRoot && XnsAttrs != null)
\r
253 MemberInfo member = XnsAttrs.MemberInfo;
\r
254 FieldInfo fInfo = member as FieldInfo;
\r
255 PropertyInfo propInfo = member as PropertyInfo;
\r
256 XmlSerializerNamespaces xns;
\r
258 xns = (XmlSerializerNamespaces) fInfo.GetValue(o);
\r
260 xns = (XmlSerializerNamespaces) propInfo.GetValue(o,null);
\r
262 XmlQualifiedName[] qnames = xns.ToArray();
\r
263 foreach(XmlQualifiedName qname in qnames)
\r
265 if(writer.LookupPrefix(qname.Namespace) != qname.Name)
\r
266 writer.WriteAttributeString("xmlns", qname.Name, null, qname.Namespace);
\r
270 //Serialize the Attributes.
\r
271 foreach(XmlAttributes attrs in attrList)
\r
273 MemberInfo member = attrs.MemberInfo;
\r
274 FieldInfo fInfo = member as FieldInfo;
\r
275 PropertyInfo propInfo = member as PropertyInfo;
\r
276 Type attributeType;
\r
277 object attributeValue;
\r
278 string attributeValString;
\r
279 string attributeName;
\r
280 string attributeNs;
\r
284 attributeType = fInfo.FieldType;
\r
285 attributeValue = fInfo.GetValue(o);
\r
287 else if(propInfo != null)
\r
289 attributeType = propInfo.PropertyType;
\r
290 attributeValue = propInfo.GetValue(o,null);
\r
293 throw new Exception("Should never Happen. Neither field or property");
\r
295 attributeName = attrs.GetAttributeName(attributeType, member.Name);
\r
296 attributeNs = attrs.GetAttributeNamespace(attributeType);
\r
298 if(attributeValue is XmlQualifiedName)
\r
300 XmlQualifiedName qname = (XmlQualifiedName) attributeValue;
\r
303 writer.WriteStartAttribute(attributeName, attributeNs);
\r
304 writer.WriteQualifiedName(qname.Name, qname.Namespace);
\r
305 writer.WriteEndAttribute();
\r
309 else if(attributeValue is XmlQualifiedName[])
\r
311 XmlQualifiedName[] qnames = (XmlQualifiedName[]) attributeValue;
\r
312 writer.WriteStartAttribute(attributeName, attributeNs);
\r
314 foreach(XmlQualifiedName qname in qnames)
\r
319 writer.WriteWhitespace(" ");
\r
320 writer.WriteQualifiedName(qname.Name, qname.Namespace);
\r
322 writer.WriteEndAttribute();
\r
325 else if(attributeValue is XmlAttribute[])
\r
327 XmlAttribute[] xmlattrs = (XmlAttribute[]) attributeValue;
\r
328 foreach(XmlAttribute xmlattr in xmlattrs)
\r
329 xmlattr.WriteTo(writer);
\r
332 attributeValString = GetXmlValue(attributeValue);
\r
334 if(attributeValString != GetXmlValue(attrs.XmlDefaultValue))
\r
336 writer.WriteAttributeString(attributeName, attributeNs, attributeValString);
\r
340 //Serialize Elements
\r
341 foreach(XmlAttributes attrs in elemList)
\r
343 MemberInfo member = attrs.MemberInfo;
\r
344 FieldInfo fInfo = member as FieldInfo;
\r
345 PropertyInfo propInfo = member as PropertyInfo;
\r
347 object elementValue;
\r
348 string elementName;
\r
353 elementType = fInfo.FieldType;
\r
354 elementValue = fInfo.GetValue(o);
\r
356 else if(propInfo != null)
\r
358 elementType = propInfo.PropertyType;
\r
359 elementValue = propInfo.GetValue(o,null);
\r
361 else throw new Exception("should never happpen. Element is neither field nor property");
\r
363 elementName = attrs.GetElementName(elementType, member.Name);
\r
364 elementNs = attrs.GetElementNamespace(elementType);
\r
366 WriteElement(writer, attrs, elementName, elementNs, elementType, elementValue);
\r
370 private void WriteElement(XmlWriter writer, XmlAttributes attrs,
\r
371 string name, string ns, Type type, Object value)
\r
373 if(IsInbuiltType(type))
\r
375 writer.WriteElementString(name, ns, "" + GetXmlValue(value));
\r
377 else if(attrs.XmlText != null && value != null)
\r
379 if(type == typeof(object[]))
\r
382 else if(type == typeof(string[]))
\r
385 else if(type == typeof(XmlNode))
\r
387 ((XmlNode)value).WriteTo(writer);
\r
389 else if(type == typeof(XmlNode[]))
\r
391 XmlNode[] nodes = (XmlNode[])value;
\r
392 foreach(XmlNode node in nodes)
\r
393 node.WriteTo(writer);
\r
396 else if(type.IsArray && value != null)
\r
398 writer.WriteStartElement(name, ns);
\r
399 SerializeArray(writer, value);
\r
400 writer.WriteEndElement();
\r
402 else if(value is ICollection)
\r
404 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
\r
405 //Find a non indexer Count Property with return type of int
\r
406 PropertyInfo countProp = type.GetProperty("Count", flags, null, typeof(int),new Type[0], null);
\r
407 PropertyInfo itemProp = type.GetProperty("Item", flags, null, null, new Type[1]{typeof(int)}, null);
\r
408 int count = (int)countProp.GetValue(value,null);
\r
409 object[] items = new object[1];
\r
413 for(int i=0;i<count;i++)
\r
416 object itemval = itemProp.GetValue(value, items);
\r
419 if(itemval != null)
\r
421 itemName = attrs.GetElementName(itemval.GetType(), name);
\r
422 itemNs = attrs.GetElementNamespace(itemval.GetType());
\r
423 writer.WriteStartElement(itemName, itemNs);
\r
424 SerializeMembers(writer, itemval, false);
\r
425 writer.WriteEndElement();
\r
430 else if(value is IEnumerable)
\r
434 else if(type.IsEnum)
\r
438 else if(value != null) //Complex Type?
\r
440 string itemName = attrs.GetElementName(value.GetType(), name);
\r
441 string itemNs = attrs.GetElementNamespace(value.GetType());
\r
442 writer.WriteStartElement(itemName, itemNs);
\r
443 SerializeMembers(writer, value, false);
\r
444 writer.WriteEndElement();
\r
451 private void SerializeArray( XmlWriter writer, object o)
\r
457 /// If the type is a string, valuetype or primitive type we do not populate the TypeTable.
\r
458 /// If the type is an array, we populate the TypeTable with Element type of the array.
\r
459 /// If the type implements ICollection, it is handled differently. We do not care for its members.
\r
460 /// If the type implements IEnumberable, we check that it implements Add(). Don't care for members.
\r
462 private void FillTypeTable(Type type)
\r
464 if(typeTable.Contains(type))
\r
467 //For value types and strings we don't need the members.
\r
468 //FIXME: We will need the enum types probably.
\r
469 if(IsInbuiltType(type))
\r
472 //Array, ICollection and IEnumberable are treated differenty
\r
475 FillArrayType(type);
\r
478 else if(type.IsEnum)
\r
485 //There must be a public constructor
\r
486 if(!HasDefaultConstructor(type))
\r
488 throw new Exception("Can't Serialize Type " + type.Name + " since it does not have default Constructor");
\r
491 if(type.GetInterface("ICollection") == typeof(System.Collections.ICollection))
\r
493 FillICollectionType(type);
\r
497 if(type.GetInterface("IEnumerable") == typeof(System.Collections.IEnumerable))
\r
499 FillIEnumerableType(type);
\r
504 //Add the Class to the hashtable.
\r
505 //Each value of the hashtable has two objects, one is the hashtable with key of membername (for deserialization)
\r
506 //Other is an Array of XmlSerializernames, Array of XmlAttributes & Array of XmlElements.
\r
507 Object[] memberObj = new Object[4];
\r
508 typeTable.Add(type,memberObj);
\r
510 Hashtable memberTable = new Hashtable();
\r
511 memberObj[0] = memberTable;
\r
512 memberTable.Add("", XmlAttributes.FromClass(type));
\r
514 memberObj[1] = null;
\r
516 ArrayList attrList = new ArrayList();
\r
517 memberObj[2] = attrList;
\r
519 ArrayList elemList = new ArrayList();
\r
520 memberObj[3] = elemList;
\r
522 //Get the graph of the members. Graph is nothing but the order
\r
523 //in which MS implementation serializes the members.
\r
524 MemberInfo[] minfo = GetGraph(type);
\r
526 foreach(MemberInfo member in minfo)
\r
528 FieldInfo fInfo = (member as FieldInfo);
\r
529 PropertyInfo propInfo = (member as PropertyInfo);
\r
533 //If field is readOnly or const, do not serialize it.
\r
534 if(fInfo.IsLiteral || fInfo.IsInitOnly)
\r
537 XmlAttributes attrs = XmlAttributes.FromField(member,fInfo);
\r
539 //If XmlAttributes have XmlIgnore, ignore this member
\r
540 if(attrs.XmlIgnore)
\r
542 //If this member is a XmlNs type, set the XmlNs object.
\r
545 memberObj[1] = attrs;
\r
548 //If the member is a attribute Type, Add to attribute list
\r
549 if(attrs.isAttribute)
\r
550 attrList.Add(attrs);
\r
551 else //Add to elements
\r
553 elemList.Add(attrs);
\r
555 //Add in the Hashtable.
\r
556 memberTable.Add(member.Name, attrs);
\r
558 Type fieldType = fInfo.FieldType;
\r
560 if(attrs.XmlAnyAttribute != null || attrs.XmlText != null)
\r
563 if(attrs.XmlElements.Count > 0)
\r
565 foreach(XmlElementAttribute elem in attrs.XmlElements)
\r
567 if(elem.Type != null)
\r
568 FillTypeTable(elem.Type);
\r
570 FillTypeTable(fieldType);
\r
575 if(!IsInbuiltType(fieldType))
\r
576 FillTypeTable(fieldType);
\r
578 else if(propInfo != null)
\r
580 //If property is readonly or writeonly, do not serialize it.
\r
581 //Exceptions are properties whose return type is array, ICollection or IEnumerable
\r
582 //Indexers are not serialized unless the class Implements ICollection.
\r
583 if(!(propInfo.PropertyType.IsArray || Implements(propInfo.PropertyType,typeof(ICollection)) ||
\r
584 (propInfo.PropertyType != typeof(string) && Implements(propInfo.PropertyType,typeof(IEnumerable)))))
\r
586 if(!(propInfo.CanRead && propInfo.CanWrite) || propInfo.GetIndexParameters().Length != 0)
\r
589 XmlAttributes attrs = XmlAttributes.FromProperty(member,propInfo);
\r
590 //If XmlAttributes have XmlIgnore, ignore this member
\r
591 if(attrs.XmlIgnore)
\r
594 //If this member is a XmlNs type, set the XmlNs object.
\r
597 memberObj[1] = attrs;
\r
600 //If the member is a attribute Type, Add to attribute list
\r
601 if(attrs.isAttribute)
\r
602 attrList.Add(attrs);
\r
603 else //Add to elements
\r
605 elemList.Add(attrs);
\r
608 //OtherWise add in the Hashtable.
\r
609 memberTable.Add(member.Name, attrs);
\r
611 Type propType = propInfo.PropertyType;
\r
613 if(attrs.XmlAnyAttribute != null || attrs.XmlText != null)
\r
616 if(attrs.XmlElements.Count > 0)
\r
618 foreach(XmlElementAttribute elem in attrs.XmlElements)
\r
620 if(elem.Type != null)
\r
621 FillTypeTable(elem.Type);
\r
623 FillTypeTable(propType);
\r
628 if(!IsInbuiltType(propType))
\r
629 FillTypeTable(propType);
\r
632 //Sort the attributes for the members according to their Order
\r
633 //This is an extension to MS's Implementation and will be useful
\r
634 //if our reflection does not return the same order of elements
\r
637 BubbleSort(elemList,XmlAttributes.attrComparer);
\r
640 private void FillArrayType(Type type)
\r
643 throw new Exception("Should never happen. Type is not an array");
\r
645 if(type.GetArrayRank() != 1)
\r
646 throw new Exception("MultiDimensional Arrays are not Supported");
\r
648 Type arrayType = type.GetElementType();
\r
650 if(arrayType.IsArray)
\r
652 FillArrayType(arrayType);
\r
654 else if(!IsInbuiltType(arrayType))
\r
656 FillTypeTable(arrayType);
\r
660 private void FillICollectionType(Type type)
\r
662 //Must have an public Indexer that takes an integer and
\r
663 //a public Count Property which returns an int.
\r
665 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
\r
667 //Find a non indexer Count Property with return type of int
\r
668 PropertyInfo countProp = type.GetProperty("Count", flags, null, typeof(int),new Type[0], null);
\r
669 if(countProp == null || !countProp.CanRead)
\r
670 throw new Exception("Cannot Serialize "+type+" because it implements ICollectoion, but does not implement public Count property");
\r
671 //Find a indexer Item Property which takes an int
\r
672 PropertyInfo itemProp = type.GetProperty("Item", flags, null, null, new Type[1]{typeof(int)}, null);
\r
673 if(itemProp == null || !itemProp.CanRead || !itemProp.CanWrite)
\r
674 throw new Exception("Cannot Serialize "+type+" because it does not have a read/write indexer property that takes an int as argument");
\r
677 private void FillIEnumerableType(Type type)
\r
679 //Must implement a public Add method that takes a single parameter.
\r
680 //The Add method's parameter must be of the same type as is returned from
\r
681 // the Current property on the value returned from GetEnumerator, or one of that type's bases.
\r
682 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
\r
683 MethodInfo enumMethod = type.GetMethod("GetEnumerator", flags, null, new Type[0], null);
\r
684 if(enumMethod == null)
\r
685 throw new Exception("Cannot serialize "+type+" because it does not implement GetEnumerator");
\r
687 Type returnType = enumMethod.ReturnType;
\r
689 while(returnType != null)
\r
691 MethodInfo addMethod = type.GetMethod("Add", flags, null, new Type[1]{returnType},null);
\r
692 if(addMethod != null)
\r
694 returnType = returnType.BaseType;
\r
697 throw new Exception("Cannot serialize "+type+" because it does not have a Add method which takes "
\r
698 +enumMethod.ReturnType+" or one of its base types.");
\r
701 private void FillEnum(Type type)
\r
703 Hashtable memberTable = new Hashtable();
\r
704 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
\r
705 typeTable.Add(type,memberTable);
\r
706 string[] names = Enum.GetNames(type);
\r
707 foreach(string name in names)
\r
709 MemberInfo[] members = type.GetMember(name);
\r
710 if(members.Length != 1)
\r
711 throw new Exception("Should never happen. Enum member not present or more than one. "+name);
\r
712 XmlAttributes attrs = new XmlAttributes(members[0]);
\r
713 if(attrs.XmlIgnore)
\r
715 if(attrs.XmlEnum != null)
\r
717 memberTable.Add(members[0].Name, attrs.XmlEnum.Name);
\r
721 memberTable.Add(members[0].Name, members[0].Name);
\r
726 private bool HasDefaultConstructor(Type type)
\r
728 ConstructorInfo defaultConstructor = type.GetConstructor(new Type[0]);
\r
729 if(defaultConstructor == null || defaultConstructor.IsAbstract || defaultConstructor.IsStatic
\r
730 || !defaultConstructor.IsPublic)
\r
736 private bool IsInbuiltType(Type type)
\r
740 if(type.IsValueType || type == typeof(string) || type.IsPrimitive)
\r
745 private static MemberInfo[] GetGraph(Type type)
\r
747 ArrayList typeGraph = new ArrayList();
\r
748 GetGraph(type, typeGraph);
\r
749 return (MemberInfo[]) typeGraph.ToArray(typeof(MemberInfo));
\r
752 private static void GetGraph(Type type, ArrayList typeGraph)
\r
754 BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
\r
755 if(type.BaseType == null)
\r
757 GetGraph(type.BaseType,typeGraph);
\r
759 typeGraph.AddRange(type.GetFields(flags));
\r
760 typeGraph.AddRange(type.GetProperties(flags));
\r
763 private string GetXmlValue(object value)
\r
769 Type type = value.GetType();
\r
771 if(typeTable.ContainsKey(type))
\r
773 Hashtable memberTable = (Hashtable)(typeTable[type]);
\r
774 if(type.IsDefined(typeof(FlagsAttribute),false))
\r
776 //If value is exactly a single enum member
\r
777 if(memberTable.Contains(value.ToString()))
\r
778 return (string)memberTable[value.ToString()];
\r
780 string retval = "";
\r
782 int enumval = (int) value;
\r
783 string[] names = Enum.GetNames(type);
\r
784 foreach(string key in names)
\r
786 if(!memberTable.ContainsKey(key))
\r
788 //Otherwise multiple values.
\r
789 int val = (int)Enum.Parse(type, key);
\r
790 if(val != 0 && (enumval & val) == val)
\r
792 retval += " " + (string)memberTable[Enum.GetName(type,val)];
\r
795 retval = retval.Trim();
\r
796 if(retval.Length == 0)
\r
802 if(memberTable.ContainsKey(value.ToString()))
\r
803 return (string)memberTable[value.ToString()];
\r
810 throw new Exception("Unknown Enumeration");
\r
815 return (bool)value ? "true" : "false";
\r
817 if(value is XmlQualifiedName)
\r
819 if(((XmlQualifiedName)value).IsEmpty)
\r
822 return (value==null) ? null : value.ToString();
\r
825 private static void ProcessAttributes(XmlAttributes attrs, Hashtable memberTable)
\r
827 if(attrs.XmlAnyAttribute != null)
\r
830 foreach(XmlAnyElementAttribute anyelem in attrs.XmlAnyElements)
\r
832 memberTable.Add(new XmlQualifiedName(anyelem.Name, anyelem.Namespace), attrs);
\r
834 if(attrs.XmlArray != null)
\r
837 foreach(XmlArrayItemAttribute item in attrs.XmlArrayItems)
\r
839 memberTable.Add(new XmlQualifiedName(item.ElementName, item.Namespace), attrs);
\r
841 if(attrs.XmlAttribute != null)
\r
843 memberTable.Add(new XmlQualifiedName(attrs.XmlAttribute.AttributeName,attrs.XmlAttribute.Namespace), attrs);
\r
845 if(attrs.XmlChoiceIdentifier != null)
\r
848 foreach(XmlElementAttribute elem in attrs.XmlElements)
\r
850 memberTable.Add(new XmlQualifiedName(elem.ElementName, elem.Namespace), attrs);
\r
852 if(attrs.XmlEnum != null)
\r
855 if(attrs.XmlType != null)
\r
857 memberTable.Add(new XmlQualifiedName(attrs.XmlType.TypeName, attrs.XmlType.Namespace), attrs);
\r
861 private bool Implements(Type type, Type interfaceType)
\r
863 if(type.GetInterface(interfaceType.FullName) == interfaceType)
\r
867 private static void BubbleSort(ArrayList array, IComparer comparer)
\r
869 int len = array.Count;
\r
871 for (int i=0; i < len; i++)
\r
873 for (int j=0; j < len -i -1; j++)
\r
877 if (comparer.Compare( obj2 , obj1 ) < 0)
\r