PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Ratings/RatingsFile.cs

https://github.com/Dracontis/Ratings
C# | 252 lines | 186 code | 23 blank | 43 comment | 12 complexity | 17dbe528d8efdaa522ada731c2144d0e MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml.Linq;
  6. using System.Xml.XPath;
  7. using System.IO;
  8. /**
  9. * Thread safe class to work with simple XML files.
  10. * It has such structure:
  11. * 1. ROOT element, that nessessary for all XML files. There are inner variable which represents it.
  12. * 2. Element that represent class, they were created when Create() function called and they were hardcoded.
  13. * 3. Elements that represent variables of the class. You can specify as much as you want, but this class created to work
  14. * with one node, named 'record', which set by default to all methods
  15. */
  16. namespace Ratings
  17. {
  18. class RatingsXMLFile
  19. {
  20. // Constants
  21. private string FILENAME = "ratings_"+ DateTime.Now.ToString("d.M.yyyy") +".xml";
  22. private const int SQUAD_COUNT = 4;
  23. // Variables
  24. private static volatile XElement RootElement = null;
  25. private static object syncRoot = new Object();
  26. #region Initializtion
  27. public RatingsXMLFile(String filename = null)
  28. {
  29. if (filename != null)
  30. this.FILENAME = filename;
  31. loadRoot();
  32. }
  33. private void loadRoot()
  34. {
  35. if (File.Exists(FILENAME))
  36. {
  37. RootElement = XElement.Load(FILENAME);
  38. }
  39. else
  40. {
  41. Create();
  42. RootElement = XElement.Load(FILENAME);
  43. }
  44. }
  45. #endregion
  46. #region Create, Save, Reset and Count functions
  47. /// <summary>
  48. /// Create new XML file
  49. /// </summary>
  50. private void Create()
  51. {
  52. XElement[] squads = new XElement[SQUAD_COUNT];
  53. for (int i = 0; i < SQUAD_COUNT; i++)
  54. squads[i] = new XElement("squad" + (i + 1));
  55. XDocument xDoc = new XDocument(
  56. new XDeclaration("1.0", "UTF-8", null),
  57. new XElement("ROOT", squads)
  58. );
  59. xDoc.Save(FILENAME);
  60. }
  61. public int ChildrenElementsCount(String parentElementName)
  62. {
  63. XElement parentElement = RootElement.Element(parentElementName);
  64. if (parentElement == null)
  65. return 0;
  66. return parentElement.Elements().Count();
  67. }
  68. /// <summary>
  69. /// Delete existing XML file with proper FILENAME
  70. /// </summary>
  71. public void ResetFile()
  72. {
  73. if (File.Exists(FILENAME))
  74. {
  75. File.Delete(FILENAME);
  76. Create();
  77. loadRoot();
  78. }
  79. }
  80. private void Save()
  81. {
  82. RootElement.Save(FILENAME);
  83. }
  84. #endregion
  85. #region Insert, Delete functions
  86. /// <summary>
  87. /// Insert new element into specified parent element. Default name of new element is 'record'
  88. /// </summary>
  89. public void Insert(String record, String parentElementName, String newElementName = "record", List<AttributeContainer> attributes = null)
  90. {
  91. XElement parentElement = RootElement.Element(parentElementName);
  92. XElement elementForInsertion = new XElement(newElementName, record);
  93. if (attributes != null)
  94. {
  95. foreach (AttributeContainer attribute in attributes)
  96. elementForInsertion.SetAttributeValue(attribute.Name, attribute.ValueAsInt());
  97. }
  98. parentElement.Add(elementForInsertion);
  99. Save();
  100. }
  101. /// <summary>
  102. /// Delete last child element from node
  103. /// </summary>
  104. /// <param name="parentElementName">Name of element in ROOT</param>
  105. /// <param name="elementToDeletion">Name of child element which will be deleted</param>
  106. public void Delete(String parentElementName, String elementToDeletion = "record")
  107. {
  108. XElement element = RootElement.Element(parentElementName).Element(elementToDeletion);
  109. element.Remove();
  110. Save();
  111. }
  112. /// <summary>
  113. /// Delete all elements from node
  114. /// </summary>
  115. /// <param name="parentElementName">Name of element in ROOT</param>
  116. public void DeleteAll(String parentElementName)
  117. {
  118. XElement element = RootElement.Element(parentElementName);
  119. element.RemoveAll();
  120. Save();
  121. }
  122. #endregion
  123. #region GetData functions
  124. /// <summary>
  125. /// Retrieve all data from specified parent element
  126. /// </summary>
  127. /// <param name="parentElementName">Name of element in ROOT</param>
  128. public List<String> GetData(String parentElementName)
  129. {
  130. List<String> data = new List<String>();
  131. XElement parentElement = RootElement.Element(parentElementName);
  132. IEnumerable<XElement> records = parentElement.Elements();
  133. foreach (var record in records)
  134. {
  135. data.Add(record.Value);
  136. }
  137. return data;
  138. }
  139. /// <summary>
  140. /// Retrieve all data from specified parent element
  141. /// plus at the begining there will be all atributes written like "[attribute_name][attribute_value]"
  142. /// </summary>
  143. /// <param name="parentElementName">Name of element in ROOT</param>
  144. public List<String> GetDataAndAttribues(String parentElementName, List<String> attributeNames)
  145. {
  146. List<String> data = new List<String>();
  147. if (RootElement != null)
  148. {
  149. XElement parentElement = RootElement.Element(parentElementName);
  150. IEnumerable<XElement> records = parentElement.Elements();
  151. foreach (var record in records)
  152. {
  153. String insertionValue = "";
  154. foreach (String attributeName in attributeNames)
  155. {
  156. try
  157. {
  158. insertionValue = attributeName + record.Attribute(attributeName).Value + "; ";
  159. }
  160. catch
  161. {
  162. continue;
  163. }
  164. }
  165. insertionValue += record.Value;
  166. data.Add(insertionValue);
  167. }
  168. }
  169. return data;
  170. }
  171. #endregion
  172. #region Group existed entries by its id
  173. /// <summary>
  174. /// Group elemenets by id and give away this data
  175. /// </summary>
  176. /// <param name="parentElementName">Name of element in ROOT</param>
  177. public List<List<String>> GetListOfElementValuesGroupedById(String parentElementName)
  178. {
  179. // Retrieve all elements from parent node
  180. List<String> data = new List<String>();
  181. XElement parentElement = RootElement.Element(parentElementName);
  182. IEnumerable<XElement> records = parentElement.Elements();
  183. List<String> dataWithNoId = new List<String>();
  184. List<List<String>> dataWithSameId = getListOfElementsWithSameId(records, out dataWithNoId);
  185. DeleteAll(parentElementName);
  186. // Restore previous data, which has no need in merge
  187. foreach (String previousData in dataWithNoId)
  188. {
  189. Insert(previousData, parentElementName);
  190. }
  191. return dataWithSameId;
  192. }
  193. private List<List<String>> getListOfElementsWithSameId(IEnumerable<XElement> records, out List<String> elementsWithNoId)
  194. {
  195. List<String> positionSaver = new List<String>(); // Id list. It will help to find data index for that id.
  196. List<List<String>> result = new List<List<String>>();
  197. List<String> noIdResult = new List<String>();
  198. foreach (var record in records)
  199. {
  200. String recordValue = record.Value;
  201. String recordId = "0";
  202. try
  203. {
  204. recordId = record.Attribute("id").Value;
  205. }
  206. catch
  207. {
  208. noIdResult.Add(recordValue);
  209. continue;
  210. }
  211. if (!positionSaver.Contains(recordId))
  212. {
  213. positionSaver.Add(recordId);
  214. List<String> newRecordList = new List<String>();
  215. newRecordList.Add(recordValue);
  216. result.Add(newRecordList);
  217. }
  218. else
  219. {
  220. int index = positionSaver.IndexOf(recordId);
  221. result[index].Add(recordValue);
  222. }
  223. }
  224. elementsWithNoId = noIdResult;
  225. return result;
  226. }
  227. #endregion
  228. }
  229. }