TopXmlParser.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text;
  5. using System.Text.RegularExpressions;
  6. using System.Threading;
  7. using System.Xml.Serialization;
  8. namespace Top.Api.Parser
  9. {
  10. /// <summary>
  11. /// TOP XML响应通用解释器。
  12. /// </summary>
  13. public class TopXmlParser<T> : ITopParser<T> where T : TopResponse
  14. {
  15. private static readonly Regex regex = new Regex("<(\\w+?)[ >]", RegexOptions.Compiled);
  16. private static readonly ReaderWriterLock rwLock = new ReaderWriterLock();
  17. private static readonly Dictionary<string, XmlSerializer> parsers = new Dictionary<string, XmlSerializer>();
  18. #region ITopParser Members
  19. public T Parse(string body, Type type)
  20. {
  21. return DoParse(body, type);
  22. }
  23. public T Parse(string body)
  24. {
  25. Type type = typeof(T);
  26. return DoParse(body, type);
  27. }
  28. #endregion
  29. private T DoParse(string body, Type type)
  30. {
  31. string rootTagName = GetRootElement(body);
  32. string key = type.FullName;
  33. if (Constants.ERROR_RESPONSE.Equals(rootTagName))
  34. {
  35. key += ("_" + Constants.ERROR_RESPONSE);
  36. }
  37. XmlSerializer serializer = null;
  38. bool incl = false;
  39. rwLock.AcquireReaderLock(50);
  40. try
  41. {
  42. if (rwLock.IsReaderLockHeld)
  43. {
  44. incl = parsers.TryGetValue(key, out serializer);
  45. }
  46. }
  47. finally
  48. {
  49. if (rwLock.IsReaderLockHeld)
  50. {
  51. rwLock.ReleaseReaderLock();
  52. }
  53. }
  54. if (!incl || serializer == null)
  55. {
  56. XmlAttributes rootAttrs = new XmlAttributes();
  57. rootAttrs.XmlRoot = new XmlRootAttribute(rootTagName);
  58. XmlAttributeOverrides attrOvrs = new XmlAttributeOverrides();
  59. attrOvrs.Add(type, rootAttrs);
  60. serializer = new XmlSerializer(type, attrOvrs);
  61. rwLock.AcquireWriterLock(50);
  62. try
  63. {
  64. if (rwLock.IsWriterLockHeld)
  65. {
  66. parsers[key] = serializer;
  67. }
  68. }
  69. finally
  70. {
  71. if (rwLock.IsWriterLockHeld)
  72. {
  73. rwLock.ReleaseWriterLock();
  74. }
  75. }
  76. }
  77. object obj = null;
  78. using (System.IO.Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(body)))
  79. {
  80. obj = serializer.Deserialize(stream);
  81. }
  82. T rsp = (T)obj;
  83. if (rsp != null)
  84. {
  85. rsp.Body = body;
  86. }
  87. return rsp;
  88. }
  89. /// <summary>
  90. /// 获取XML响应的根节点名称
  91. /// </summary>
  92. private string GetRootElement(string body)
  93. {
  94. Match match = regex.Match(body);
  95. if (match.Success)
  96. {
  97. return match.Groups[1].ToString();
  98. }
  99. else
  100. {
  101. throw new TopException("Invalid XML response format!");
  102. }
  103. }
  104. }
  105. }