XmlWriter.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Reflection;
  5. using System.Text;
  6. namespace Top.Api.Util
  7. {
  8. public class XmlWriter
  9. {
  10. private StringBuilder buf = new StringBuilder();
  11. private Stack<object> calls = new Stack<object>();
  12. private string rootTagName;
  13. private Type stopType;
  14. private IDictionary<string, object> stopProps;
  15. public XmlWriter(string rootTagName, Type stopType)
  16. {
  17. this.rootTagName = rootTagName;
  18. this.stopType = stopType;
  19. if (stopType != null)
  20. {
  21. this.stopProps = GetStopProps(stopType);
  22. }
  23. }
  24. public XmlWriter()
  25. : this(null, null)
  26. {
  27. }
  28. public string Write(object obj)
  29. {
  30. buf.Length = 0;
  31. string tagName = rootTagName;
  32. if (tagName == null)
  33. {
  34. tagName = StringUtil.ToCamelStyle(obj.GetType().Name);
  35. }
  36. AddPair(tagName, obj);
  37. return buf.ToString();
  38. }
  39. private void Value(object obj)
  40. {
  41. if (obj == null || Cyclic(obj))
  42. {
  43. AddObject(null);
  44. }
  45. else
  46. {
  47. calls.Push(obj);
  48. Type objType = obj.GetType();
  49. if (typeof(IDictionary).IsAssignableFrom(objType))
  50. {
  51. AddDictionary(obj as IDictionary);
  52. }
  53. else if (typeof(ICollection).IsAssignableFrom(objType))
  54. {
  55. AddCollection(obj as ICollection);
  56. }
  57. else if (objType.IsArray)
  58. {
  59. AddArray(obj);
  60. }
  61. else if (typeof(DateTime) == objType)
  62. {
  63. AddDateTime((DateTime)obj);
  64. }
  65. else if (typeof(bool) == objType)
  66. {
  67. AddBool((bool)obj);
  68. }
  69. else if (typeof(string) == objType || typeof(Type) == objType)
  70. {
  71. AddString(obj);
  72. }
  73. else if (objType.IsPrimitive)
  74. {
  75. AddString(obj);
  76. }
  77. else
  78. {
  79. AddBean(obj);
  80. }
  81. calls.Pop();
  82. }
  83. }
  84. private bool Cyclic(object obj)
  85. {
  86. Stack<object>.Enumerator em = calls.GetEnumerator();
  87. while (em.MoveNext())
  88. {
  89. object called = em.Current;
  90. if (obj == called) return true;
  91. }
  92. return false;
  93. }
  94. private void AddBean(object obj)
  95. {
  96. bool isChildren = stopType != null && stopType.IsAssignableFrom(obj.GetType());
  97. PropertyInfo[] props = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
  98. foreach (PropertyInfo prop in props)
  99. {
  100. string name = prop.Name;
  101. if (isChildren && stopProps.ContainsKey(name))
  102. {
  103. continue;
  104. }
  105. object value = prop.GetValue(obj, new object[] { });
  106. if (value != null)
  107. {
  108. string newName = StringUtil.ToCamelStyle(name);
  109. AddPair(newName, value);
  110. }
  111. }
  112. }
  113. private void AddDictionary(IDictionary obj)
  114. {
  115. foreach (DictionaryEntry entry in obj)
  116. {
  117. string strKey = entry.Key.ToString();
  118. AddPair(strKey, entry.Value);
  119. }
  120. }
  121. private void AddCollection(ICollection obj)
  122. {
  123. string tagName = null;
  124. foreach (object item in obj)
  125. {
  126. if (tagName == null)
  127. {
  128. object[] apiListTypes = item.GetType().GetCustomAttributes(typeof(ApiListTypeAttribute), false);
  129. if (apiListTypes != null && apiListTypes.Length > 0)
  130. {
  131. tagName = ((ApiListTypeAttribute) apiListTypes[0]).Value;
  132. }
  133. else
  134. {
  135. tagName = StringUtil.ToCamelStyle(obj.GetType().Name);
  136. }
  137. }
  138. AddPair(tagName, item);
  139. }
  140. }
  141. private void AddArray(object obj)
  142. {
  143. string tagName = null;
  144. Array.ForEach(obj as object[], item =>
  145. {
  146. if (tagName == null)
  147. {
  148. tagName = StringUtil.ToCamelStyle(obj.GetType().Name);
  149. }
  150. AddPair(tagName, item);
  151. });
  152. }
  153. private void AddBool(bool value)
  154. {
  155. AddObject(value ? "true" : "false");
  156. }
  157. private void AddDateTime(DateTime value)
  158. {
  159. AddObject(StringUtil.FormatDateTime(value));
  160. }
  161. private void AddString(object obj)
  162. {
  163. AddObject(StringUtil.EscapeXml(obj.ToString()));
  164. }
  165. private void AddObject(object obj)
  166. {
  167. buf.Append(obj);
  168. }
  169. private void AddPair(string name, object value)
  170. {
  171. StartTag(name);
  172. Value(value);
  173. EndTag(name);
  174. }
  175. private void StartTag(string tagName)
  176. {
  177. buf.Append("<");
  178. buf.Append(tagName);
  179. buf.Append(">");
  180. }
  181. private void EndTag(string tagName)
  182. {
  183. buf.Append("</");
  184. buf.Append(tagName);
  185. buf.Append(">");
  186. }
  187. private IDictionary<string, object> GetStopProps(Type type)
  188. {
  189. IDictionary<string, object> stopProps = new Dictionary<string, object>();
  190. PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty);
  191. foreach (PropertyInfo prop in props)
  192. {
  193. stopProps.Add(prop.Name, null);
  194. }
  195. return stopProps;
  196. }
  197. }
  198. }