QimenCloudXmlParser.cs 3.5 KB

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