PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/ThinkEmailFomatter/Utilities/Extensions/XmlDocumentExt.cs

https://bitbucket.org/nicdao/frg-think-emailformatter
C# | 142 lines | 118 code | 8 blank | 16 comment | 35 complexity | 30d7bc72e6a9cfc7a8f0cea96cbe27e1 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Text;
  6. using System.Xml;
  7. using System.Collections;
  8. namespace ThinkEmailFormatter.Models.Extensions
  9. {
  10. public static class XmlDocumentExt
  11. {
  12. public static string XmlToJSON(this XmlDocument xmlDoc)
  13. {
  14. StringBuilder sbJSON = new StringBuilder();
  15. sbJSON.Append("{ ");
  16. XmlToJSONnode(sbJSON, xmlDoc.DocumentElement, true);
  17. sbJSON.Append("}");
  18. return sbJSON.ToString();
  19. }
  20. // XmlToJSONnode: Output an XmlElement, possibly as part of a higher array
  21. private static void XmlToJSONnode(StringBuilder sbJSON, XmlElement node, bool showNodeName)
  22. {
  23. if (showNodeName)
  24. sbJSON.Append("\"" + SafeJSON(node.Name) + "\": ");
  25. sbJSON.Append("{");
  26. // Build a sorted list of key-value pairs
  27. // where key is case-sensitive nodeName
  28. // value is an ArrayList of string or XmlElement
  29. // so that we know whether the nodeName is an array or not.
  30. SortedList childNodeNames = new SortedList();
  31. // Add in all node attributes
  32. if (node.Attributes != null)
  33. foreach (XmlAttribute attr in node.Attributes)
  34. StoreChildNode(childNodeNames, attr.Name, attr.InnerText);
  35. // Add in all nodes
  36. foreach (XmlNode cnode in node.ChildNodes)
  37. {
  38. if (cnode is XmlText)
  39. StoreChildNode(childNodeNames, "value", cnode.InnerText);
  40. else if (cnode is XmlElement)
  41. StoreChildNode(childNodeNames, cnode.Name, cnode);
  42. }
  43. // Now output all stored info
  44. foreach (string childname in childNodeNames.Keys)
  45. {
  46. ArrayList alChild = (ArrayList)childNodeNames[childname];
  47. if (alChild.Count == 1)
  48. OutputNode(childname, alChild[0], sbJSON, true);
  49. else
  50. {
  51. sbJSON.Append(" \"" + SafeJSON(childname) + "\": [ ");
  52. foreach (object Child in alChild)
  53. OutputNode(childname, Child, sbJSON, false);
  54. sbJSON.Remove(sbJSON.Length - 2, 2);
  55. sbJSON.Append(" ], ");
  56. }
  57. }
  58. sbJSON.Remove(sbJSON.Length - 2, 2);
  59. sbJSON.Append(" }");
  60. }
  61. // StoreChildNode: Store data associated with each nodeName
  62. // so that we know whether the nodeName is an array or not.
  63. private static void StoreChildNode(SortedList childNodeNames, string nodeName, object nodeValue)
  64. {
  65. // Pre-process contraction of XmlElement-s
  66. if (nodeValue is XmlElement)
  67. {
  68. // Convert <aa></aa> into "aa":null
  69. // <aa>xx</aa> into "aa":"xx"
  70. XmlNode cnode = (XmlNode)nodeValue;
  71. if (cnode.Attributes.Count == 0)
  72. {
  73. XmlNodeList children = cnode.ChildNodes;
  74. if (children.Count == 0)
  75. nodeValue = null;
  76. else if (children.Count == 1 && (children[0] is XmlText))
  77. nodeValue = ((XmlText)(children[0])).InnerText;
  78. }
  79. }
  80. // Add nodeValue to ArrayList associated with each nodeName
  81. // If nodeName doesn't exist then add it
  82. object oValuesAL = childNodeNames[nodeName];
  83. ArrayList ValuesAL;
  84. if (oValuesAL == null)
  85. {
  86. ValuesAL = new ArrayList();
  87. childNodeNames[nodeName] = ValuesAL;
  88. }
  89. else
  90. ValuesAL = (ArrayList)oValuesAL;
  91. ValuesAL.Add(nodeValue);
  92. }
  93. private static void OutputNode(string childname, object alChild, StringBuilder sbJSON, bool showNodeName)
  94. {
  95. if (alChild == null)
  96. {
  97. if (showNodeName)
  98. sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
  99. sbJSON.Append("null");
  100. }
  101. else if (alChild is string)
  102. {
  103. if (showNodeName)
  104. sbJSON.Append("\"" + SafeJSON(childname) + "\": ");
  105. string sChild = (string)alChild;
  106. sChild = sChild.Trim();
  107. sbJSON.Append("\"" + SafeJSON(sChild) + "\"");
  108. }
  109. else
  110. XmlToJSONnode(sbJSON, (XmlElement)alChild, showNodeName);
  111. sbJSON.Append(", ");
  112. }
  113. // Make a string safe for JSON
  114. private static string SafeJSON(string sIn)
  115. {
  116. StringBuilder sbOut = new StringBuilder(sIn.Length);
  117. foreach (char ch in sIn)
  118. {
  119. if (Char.IsControl(ch) || ch == '\'')
  120. {
  121. int ich = (int)ch;
  122. sbOut.Append(@"\u" + ich.ToString("x4"));
  123. continue;
  124. }
  125. else if (ch == '\"' || ch == '\\' || ch == '/')
  126. {
  127. sbOut.Append('\\');
  128. }
  129. sbOut.Append(ch);
  130. }
  131. return sbOut.ToString();
  132. }
  133. }
  134. }