XmlSerializationWriterInterpreter.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //
  2. // XmlSerializationWriterInterpreter.cs:
  3. //
  4. // Author:
  5. // Lluis Sanchez Gual ([email protected])
  6. //
  7. // (C) 2002, 2003 Ximian, Inc. http://www.ximian.com
  8. //
  9. using System;
  10. using System.Collections;
  11. using System.Reflection;
  12. namespace System.Xml.Serialization
  13. {
  14. internal class XmlSerializationWriterInterpreter: XmlSerializationWriter
  15. {
  16. XmlTypeMapping _typeMap;
  17. public XmlSerializationWriterInterpreter(XmlTypeMapping typeMap)
  18. {
  19. _typeMap = typeMap;
  20. }
  21. protected override void InitCallbacks ()
  22. {
  23. }
  24. internal override void WriteObject (object ob)
  25. {
  26. WriteObject (_typeMap, ob, _typeMap.ElementName, _typeMap.Namespace, true, false);
  27. }
  28. void WriteObject (XmlTypeMapping typeMap, object ob, string element, string namesp, bool isNullable, bool needType)
  29. {
  30. if (ob == null)
  31. {
  32. if (isNullable) WriteNullTagLiteral(element, namesp);
  33. return;
  34. }
  35. XmlTypeMapping map = typeMap.GetRealTypeMap (ob.GetType().FullName);
  36. if (map != typeMap) needType = true;
  37. switch (map.TypeData.SchemaType)
  38. {
  39. case SchemaTypes.Class: WriteObjectElement (map, ob, element, namesp, needType); break;
  40. case SchemaTypes.Array: WriteListElement (map, ob, element, namesp, needType); break;
  41. case SchemaTypes.XmlNode: WriteXmlNodeElement (map, ob, element, namesp, needType); break;
  42. }
  43. }
  44. void WriteObjectElement (XmlTypeMapping typeMap, object ob, string element, string namesp, bool needType)
  45. {
  46. WriteStartElement(element, namesp, ob);
  47. if (needType)
  48. WriteXsiType(typeMap.XmlType, typeMap.Namespace);
  49. ClassMap map = (ClassMap)typeMap.ObjectMap;
  50. ICollection attributes = map.AttributeMembers;
  51. if (attributes != null)
  52. {
  53. foreach (XmlTypeMapMemberAttribute attr in attributes)
  54. WriteAttribute(attr.AttributeName, attr.Namespace, XmlCustomFormatter.ToXmlString (attr.GetValue(ob)));
  55. }
  56. ICollection members = map.ElementMembers;
  57. if (members != null)
  58. {
  59. foreach (XmlTypeMapMemberElement member in members)
  60. {
  61. object memberValue = member.GetValue (ob);
  62. if (member is XmlTypeMapMemberList)
  63. {
  64. if (memberValue != null) {
  65. XmlTypeMapMemberList mm = (XmlTypeMapMemberList)member;
  66. WriteStartElement(mm.ElementName, mm.Namespace, memberValue);
  67. WriteListContent (member.TypeData, (ListMap) mm.ListTypeMapping.ObjectMap, memberValue);
  68. WriteEndElement (memberValue);
  69. }
  70. }
  71. else if (member is XmlTypeMapMemberFlatList)
  72. {
  73. if (memberValue != null)
  74. WriteListContent (member.TypeData, ((XmlTypeMapMemberFlatList)member).ListMap, memberValue);
  75. }
  76. else
  77. {
  78. XmlTypeMapElementInfo elem = member.FindElement (ob, memberValue);
  79. WriteMemberElement (elem, memberValue);
  80. }
  81. }
  82. }
  83. WriteEndElement (ob);
  84. }
  85. void WriteMemberElement (XmlTypeMapElementInfo elem, object memberValue)
  86. {
  87. if (elem.IsPrimitive)
  88. {
  89. if (elem.TypeData.SchemaType == SchemaTypes.XmlNode)
  90. WriteElementLiteral(((XmlNode)memberValue), elem.ElementName, elem.Namespace, elem.IsNullable, false);
  91. else if (elem.IsNullable)
  92. WriteNullableStringLiteral (elem.ElementName, elem.Namespace, XmlCustomFormatter.ToXmlString (memberValue));
  93. else
  94. WriteElementString (elem.ElementName, elem.Namespace, XmlCustomFormatter.ToXmlString (memberValue));
  95. }
  96. else
  97. WriteObject (elem.MappedType, memberValue, elem.ElementName, elem.Namespace, elem.IsNullable, false);
  98. }
  99. void WriteListElement (XmlTypeMapping typeMap, object ob, string element, string namesp, bool needType)
  100. {
  101. WriteStartElement(element, namesp, ob);
  102. if (needType)
  103. WriteXsiType(typeMap.XmlType, typeMap.Namespace);
  104. WriteListContent (typeMap.TypeData, (ListMap) typeMap.ObjectMap, ob);
  105. WriteEndElement (ob);
  106. }
  107. void WriteListContent (TypeData listType, ListMap map, object ob)
  108. {
  109. if (listType.Type.IsArray)
  110. {
  111. Array array = (Array)ob;
  112. for (int n=0; n<array.Length; n++)
  113. {
  114. object item = array.GetValue (n);
  115. XmlTypeMapElementInfo info = map.FindElement (item);
  116. if (info != null) WriteMemberElement (info, item);
  117. else if (item != null) throw CreateUnknownTypeException (item);
  118. }
  119. }
  120. else if (ob is ICollection)
  121. {
  122. int count = (int) listType.Type.GetProperty ("Count").GetValue(ob,null);
  123. PropertyInfo itemProp = listType.Type.GetProperty ("Item");
  124. object[] index = new object[1];
  125. for (int n=0; n<count; n++)
  126. {
  127. index[0] = n;
  128. object item = itemProp.GetValue (ob, index);
  129. XmlTypeMapElementInfo info = map.FindElement (item);
  130. if (info != null) WriteMemberElement (info, item);
  131. else if (item != null) throw CreateUnknownTypeException (item);
  132. }
  133. }
  134. else if (ob is IEnumerable)
  135. {
  136. IEnumerable e = (IEnumerable)ob;
  137. foreach (object item in e)
  138. {
  139. XmlTypeMapElementInfo info = map.FindElement (item);
  140. if (info != null) WriteMemberElement (info, item);
  141. else if (item != null) throw CreateUnknownTypeException (item);
  142. }
  143. }
  144. else
  145. throw new Exception ("Unsupported collection type");
  146. }
  147. void WriteXmlNodeElement (XmlTypeMapping typeMap, object ob, string element, string namesp, bool needType)
  148. {
  149. WriteElementLiteral((XmlNode)ob, "", "", true, true);
  150. }
  151. }
  152. }