using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace xmlTools { class XmlTools { private XmlDocument xdoc; private string posElement, posParentElement; private bool noBackups; /// Our constructor /// /// /// /// /// public XmlTools(string posElement, string posParentElement = "", bool noBackups = false) { this.posElement = posElement; this.posParentElement = posParentElement; this.noBackups = noBackups; } /// /// Replace all values of a element by another value /// /// /// public void replaceAll(string file, string value, string valuePositions = "") { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); List myElements = new List(); Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element if (valuePositions != "") { checkValidSpecificPositions(valuePositions, value, myElements[0].InnerText); } foreach (XmlNode element in myElements) { if (element.Name == posElement) { if (posParentElement != "" && element.ParentNode.Name != posParentElement) { continue; } if (valuePositions == "") //replace every value for the new { element.InnerText = value; } else //replace only the specified positions by the specified values of each dimension { element.InnerText = replaceSpecificPositions(element.InnerText, value, valuePositions); } } } saveXmlFile(file); } /// /// Add values in an element /// /// /// public void addValues(string file, string values) { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); XmlTextValue myInputValues = new XmlTextValue(values); List myElements = new List(); Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element foreach (XmlNode element in myElements) { if (element.Name == posElement) { if (posParentElement != "" && element.ParentNode.Name != posParentElement) { continue; } XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); foreach (String myInputValue in myInputValues.myValues) { bool alreadyExists = false; foreach (String myXmlSubValue in myXmlSubValues.myValues) { //It already exists in the xml?? if (myInputValue == myXmlSubValue) { alreadyExists = true; break; } } //if it doesn't exists already let's add it if (!alreadyExists) { element.InnerText += " " + myInputValue; } } } } saveXmlFile(file); } /// /// Replaces a value by another /// /// /// public void replaceValue(string file, string oldValue, string newValue) { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); List myElements = new List(); Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element foreach (XmlNode element in myElements) { if (element.Name == posElement) { if (posParentElement != "" && element.ParentNode.Name != posParentElement) { continue; } XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); for (int i = 0; i < myXmlSubValues.myValues.Count; i++) { //Found a match with the old value? if (myXmlSubValues.myValues[i] == oldValue) { //replace with the new match myXmlSubValues.myValues[i] = newValue; } } element.InnerText = myXmlSubValues.ToString(); } } saveXmlFile(file); } /// /// Remove values in an element /// /// /// public void removeValues(string file, string values) { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); XmlTextValue myInputValues = new XmlTextValue(values); List myElements = new List(); Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element foreach (XmlNode element in myElements) { if (element.Name == posElement) { if (posParentElement != "" && element.ParentNode.Name != posParentElement) { continue; } XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); foreach (String myInputValue in myInputValues.myValues) { for (int i = 0; i < myXmlSubValues.myValues.Count; i++) { //It already exists in the xml? if (myInputValue == myXmlSubValues.myValues[i]) { //remove it myXmlSubValues.myValues.RemoveAt(i); break; } } } element.InnerText = myXmlSubValues.myValues.ToString(); } } saveXmlFile(file); } /// /// Change a value of element (updating all the chain) /// /// /// /// public void changeValue(string file, string newValue, string valueRelation = "", string valuePositions = "") { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); XmlNumberValue xmlLastPos = null, newXmlLastPos = null; List myElements = new List(); Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element if (valuePositions == "") { newXmlLastPos = new XmlNumberValue(newValue); } else //If specific positions to be changed are specified, just associate the newLastPos with the first replaced in the specific positions by the specific values { newXmlLastPos = new XmlNumberValue(replaceSpecificPositions(myElements[0].InnerText, newValue, valuePositions)); } if (valuePositions != "") { checkValidSpecificPositions(valuePositions, newValue, myElements[0].InnerText); } foreach (XmlNode element in myElements) { if (element.Name == this.posElement && (this.posParentElement == "" || this.posParentElement == element.ParentNode.Name)) { XmlNumberValue xmlCurrValue = new XmlNumberValue(element.InnerText); if (xmlLastPos != null) { newXmlLastPos = XmlNumberValue.sum(newXmlLastPos, XmlNumberValue.difference(xmlCurrValue, xmlLastPos)); element.InnerText = newXmlLastPos.ToString(); xmlLastPos = xmlCurrValue; } else { // first time just assign to last value if (valueRelation != "") { newXmlLastPos = XmlNumberValue.difference(newXmlLastPos, XmlNumberValue.difference(new XmlNumberValue(valueRelation), xmlCurrValue)); } xmlLastPos = xmlCurrValue; element.InnerText = newXmlLastPos.ToString(); } } } saveXmlFile(file); } /// /// Invert the values of a element name (inverts all the chain) /// /// public void invert(string file) { if (!this.noBackups) { Util.backupFile(file); } loadXmlFile(file); //Inverting the element order List invertedOrder = new List(); List myElements = new List(); Util.getAllSpecificElements(this.xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Read all and save to the list foreach (XmlNode element in myElements) //Returns all after "Oni" element { invertedOrder.Add(element.InnerText); } //Let's start taking from the list to new xml file (inverted order) int count = 0; foreach (XmlNode element in myElements) //Returns all after "Oni" element { if (element.Name == posElement) { element.InnerText = invertedOrder[invertedOrder.Count - 1 - count]; count++; } } saveXmlFile(file); } private void loadXmlFile(string file) { this.xdoc = new XmlDocument(); this.xdoc.Load(file); } private void saveXmlFile(string file) { this.xdoc.Save(file); } private void checkValidSpecificPositions(string valuePositions, string value, string firstElement) { XmlNumberValue testValuePositions = new XmlNumberValue(valuePositions); XmlNumberValue testValue = new XmlNumberValue(value); XmlNumberValue testFirstRealValue = new XmlNumberValue(firstElement); if (testValuePositions.myValues.Count != testValue.myValues.Count) //Check if there are the same number of positions for the same number of dimensions to replace { Program.printAppError(Program.appErrors.NUMBER_VALUES_TO_REPLACE_NE_AVAILABLE_VALUES, "The number of values to replace must be the same of the number of specified positions.", true); } foreach (int pos in testValuePositions.myValues) //converts automatically from double to int { if (pos > testFirstRealValue.myValues.Count - 1 || pos < 0) //Are positions valid for the current values? //-1 because starts at 0 { Program.printAppError(Program.appErrors.INVALID_POSITIONS_RANGE, "The positions values are not in the range of the value to replace (pos index < 0 or > newValueIndexesNumber).", true); } } } private string replaceSpecificPositions(string currXmlValue, string values, string valuePositions) { XmlNumberValue currentValue = new XmlNumberValue(currXmlValue); XmlNumberValue positionsValues = new XmlNumberValue(valuePositions); XmlNumberValue newValues = new XmlNumberValue(values); for (int i = 0; i < positionsValues.myValues.Count; i++) { int posToChange = (int)positionsValues.myValues[i]; currentValue.myValues[posToChange] = newValues.myValues[i]; } return currentValue.ToString(); } } }