/Ratings/RatingsFile.cs
C# | 252 lines | 186 code | 23 blank | 43 comment | 12 complexity | 17dbe528d8efdaa522ada731c2144d0e MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Xml.Linq;
- using System.Xml.XPath;
- using System.IO;
- /**
- * Thread safe class to work with simple XML files.
- * It has such structure:
- * 1. ROOT element, that nessessary for all XML files. There are inner variable which represents it.
- * 2. Element that represent class, they were created when Create() function called and they were hardcoded.
- * 3. Elements that represent variables of the class. You can specify as much as you want, but this class created to work
- * with one node, named 'record', which set by default to all methods
- */
- namespace Ratings
- {
- class RatingsXMLFile
- {
- // Constants
- private string FILENAME = "ratings_"+ DateTime.Now.ToString("d.M.yyyy") +".xml";
- private const int SQUAD_COUNT = 4;
- // Variables
- private static volatile XElement RootElement = null;
- private static object syncRoot = new Object();
-
- #region Initializtion
- public RatingsXMLFile(String filename = null)
- {
- if (filename != null)
- this.FILENAME = filename;
- loadRoot();
- }
- private void loadRoot()
- {
- if (File.Exists(FILENAME))
- {
- RootElement = XElement.Load(FILENAME);
- }
- else
- {
- Create();
- RootElement = XElement.Load(FILENAME);
- }
- }
- #endregion
- #region Create, Save, Reset and Count functions
- /// <summary>
- /// Create new XML file
- /// </summary>
- private void Create()
- {
- XElement[] squads = new XElement[SQUAD_COUNT];
- for (int i = 0; i < SQUAD_COUNT; i++)
- squads[i] = new XElement("squad" + (i + 1));
- XDocument xDoc = new XDocument(
- new XDeclaration("1.0", "UTF-8", null),
- new XElement("ROOT", squads)
- );
- xDoc.Save(FILENAME);
- }
- public int ChildrenElementsCount(String parentElementName)
- {
- XElement parentElement = RootElement.Element(parentElementName);
- if (parentElement == null)
- return 0;
- return parentElement.Elements().Count();
- }
- /// <summary>
- /// Delete existing XML file with proper FILENAME
- /// </summary>
- public void ResetFile()
- {
- if (File.Exists(FILENAME))
- {
- File.Delete(FILENAME);
- Create();
- loadRoot();
- }
- }
- private void Save()
- {
- RootElement.Save(FILENAME);
- }
- #endregion
- #region Insert, Delete functions
- /// <summary>
- /// Insert new element into specified parent element. Default name of new element is 'record'
- /// </summary>
- public void Insert(String record, String parentElementName, String newElementName = "record", List<AttributeContainer> attributes = null)
- {
- XElement parentElement = RootElement.Element(parentElementName);
- XElement elementForInsertion = new XElement(newElementName, record);
- if (attributes != null)
- {
- foreach (AttributeContainer attribute in attributes)
- elementForInsertion.SetAttributeValue(attribute.Name, attribute.ValueAsInt());
- }
- parentElement.Add(elementForInsertion);
- Save();
- }
- /// <summary>
- /// Delete last child element from node
- /// </summary>
- /// <param name="parentElementName">Name of element in ROOT</param>
- /// <param name="elementToDeletion">Name of child element which will be deleted</param>
- public void Delete(String parentElementName, String elementToDeletion = "record")
- {
- XElement element = RootElement.Element(parentElementName).Element(elementToDeletion);
- element.Remove();
- Save();
- }
- /// <summary>
- /// Delete all elements from node
- /// </summary>
- /// <param name="parentElementName">Name of element in ROOT</param>
- public void DeleteAll(String parentElementName)
- {
- XElement element = RootElement.Element(parentElementName);
- element.RemoveAll();
- Save();
- }
- #endregion
- #region GetData functions
- /// <summary>
- /// Retrieve all data from specified parent element
- /// </summary>
- /// <param name="parentElementName">Name of element in ROOT</param>
- public List<String> GetData(String parentElementName)
- {
- List<String> data = new List<String>();
- XElement parentElement = RootElement.Element(parentElementName);
- IEnumerable<XElement> records = parentElement.Elements();
- foreach (var record in records)
- {
- data.Add(record.Value);
- }
- return data;
- }
-
- /// <summary>
- /// Retrieve all data from specified parent element
- /// plus at the begining there will be all atributes written like "[attribute_name][attribute_value]"
- /// </summary>
- /// <param name="parentElementName">Name of element in ROOT</param>
- public List<String> GetDataAndAttribues(String parentElementName, List<String> attributeNames)
- {
- List<String> data = new List<String>();
- if (RootElement != null)
- {
- XElement parentElement = RootElement.Element(parentElementName);
- IEnumerable<XElement> records = parentElement.Elements();
- foreach (var record in records)
- {
- String insertionValue = "";
- foreach (String attributeName in attributeNames)
- {
- try
- {
- insertionValue = attributeName + record.Attribute(attributeName).Value + "; ";
- }
- catch
- {
- continue;
- }
- }
- insertionValue += record.Value;
- data.Add(insertionValue);
- }
- }
- return data;
- }
- #endregion
- #region Group existed entries by its id
- /// <summary>
- /// Group elemenets by id and give away this data
- /// </summary>
- /// <param name="parentElementName">Name of element in ROOT</param>
- public List<List<String>> GetListOfElementValuesGroupedById(String parentElementName)
- {
- // Retrieve all elements from parent node
- List<String> data = new List<String>();
- XElement parentElement = RootElement.Element(parentElementName);
- IEnumerable<XElement> records = parentElement.Elements();
- List<String> dataWithNoId = new List<String>();
- List<List<String>> dataWithSameId = getListOfElementsWithSameId(records, out dataWithNoId);
- DeleteAll(parentElementName);
- // Restore previous data, which has no need in merge
- foreach (String previousData in dataWithNoId)
- {
- Insert(previousData, parentElementName);
- }
- return dataWithSameId;
- }
- private List<List<String>> getListOfElementsWithSameId(IEnumerable<XElement> records, out List<String> elementsWithNoId)
- {
- List<String> positionSaver = new List<String>(); // Id list. It will help to find data index for that id.
- List<List<String>> result = new List<List<String>>();
- List<String> noIdResult = new List<String>();
- foreach (var record in records)
- {
- String recordValue = record.Value;
- String recordId = "0";
- try
- {
- recordId = record.Attribute("id").Value;
- }
- catch
- {
- noIdResult.Add(recordValue);
- continue;
- }
- if (!positionSaver.Contains(recordId))
- {
- positionSaver.Add(recordId);
- List<String> newRecordList = new List<String>();
- newRecordList.Add(recordValue);
- result.Add(newRecordList);
- }
- else
- {
- int index = positionSaver.IndexOf(recordId);
- result[index].Add(recordValue);
- }
- }
- elementsWithNoId = noIdResult;
- return result;
- }
- #endregion
- }
- }