1 |
using System; |
2 |
using System.Collections.Generic; |
3 |
using System.Text; |
4 |
using System.Xml; |
5 |
|
6 |
namespace xmlTools |
7 |
{ |
8 |
class XmlTools |
9 |
{ |
10 |
private XmlDocument xdoc; |
11 |
private string posElement, posParentElement; |
12 |
|
13 |
/// <summary> |
14 |
/// Our constructor |
15 |
/// </summary> |
16 |
/// <param name="file"></param> |
17 |
/// <param name="posElement"></param> |
18 |
/// <param name="posParentElement"></param> |
19 |
public XmlTools(string posElement, string posParentElement = "") |
20 |
{ |
21 |
this.posElement = posElement; |
22 |
this.posParentElement = posParentElement; |
23 |
} |
24 |
|
25 |
/// <summary> |
26 |
/// Replace all values of a element by another value |
27 |
/// </summary> |
28 |
/// <param name="file"></param> |
29 |
/// <param name="value"></param> |
30 |
public void replaceAll(string file, string value, string valuePositions = "") |
31 |
{ |
32 |
Util.backupFile(file); |
33 |
loadXmlFile(file); |
34 |
|
35 |
List<XmlNode> myElements = new List<XmlNode>(); |
36 |
Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements,this.posElement,this.posParentElement); //Returns all after "Oni" element |
37 |
|
38 |
if (valuePositions != "") |
39 |
{ |
40 |
checkValidSpecificPositions(valuePositions, value, myElements[0].InnerText); |
41 |
} |
42 |
|
43 |
foreach (XmlNode element in myElements) |
44 |
{ |
45 |
if (element.Name == posElement) |
46 |
{ |
47 |
if (posParentElement != "" && element.ParentNode.Name != posParentElement) |
48 |
{ |
49 |
continue; |
50 |
} |
51 |
if (valuePositions == "") //replace every value for the new |
52 |
{ |
53 |
element.InnerText = value; |
54 |
} |
55 |
else //replace only the specified positions by the specified values of each dimension |
56 |
{ |
57 |
element.InnerText = replaceSpecificPositions(element.InnerText, value, valuePositions); |
58 |
} |
59 |
|
60 |
} |
61 |
} |
62 |
|
63 |
saveXmlFile(file); |
64 |
} |
65 |
|
66 |
/// <summary> |
67 |
/// Add values in an element |
68 |
/// </summary> |
69 |
/// <param name="file"></param> |
70 |
/// <param name="value"></param> |
71 |
public void addValues(string file, string values) |
72 |
{ |
73 |
Util.backupFile(file); |
74 |
loadXmlFile(file); |
75 |
|
76 |
XmlTextValue myInputValues = new XmlTextValue(values); |
77 |
|
78 |
List<XmlNode> myElements = new List<XmlNode>(); |
79 |
Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element |
80 |
|
81 |
foreach (XmlNode element in myElements) |
82 |
{ |
83 |
if (element.Name == posElement) |
84 |
{ |
85 |
if (posParentElement != "" && element.ParentNode.Name != posParentElement) |
86 |
{ |
87 |
continue; |
88 |
} |
89 |
XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); |
90 |
|
91 |
foreach(String myInputValue in myInputValues.myValues){ |
92 |
bool alreadyExists = false; |
93 |
foreach (String myXmlSubValue in myXmlSubValues.myValues) |
94 |
{ |
95 |
//It already exists in the xml?? |
96 |
if (myInputValue == myXmlSubValue) |
97 |
{ |
98 |
alreadyExists = true; |
99 |
break; |
100 |
} |
101 |
} |
102 |
//if it doesn't exists already let's add it |
103 |
if (!alreadyExists) |
104 |
{ |
105 |
element.InnerText += " "+myInputValue; |
106 |
} |
107 |
} |
108 |
} |
109 |
} |
110 |
|
111 |
saveXmlFile(file); |
112 |
} |
113 |
|
114 |
/// <summary> |
115 |
/// Replaces a value by another |
116 |
/// </summary> |
117 |
/// <param name="currentFile"></param> |
118 |
/// <param name="replaceValue"></param> |
119 |
public void replaceValue(string file, string oldValue, string newValue) |
120 |
{ |
121 |
Util.backupFile(file); |
122 |
loadXmlFile(file); |
123 |
|
124 |
List<XmlNode> myElements = new List<XmlNode>(); |
125 |
Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element |
126 |
|
127 |
foreach (XmlNode element in myElements) |
128 |
{ |
129 |
if (element.Name == posElement) |
130 |
{ |
131 |
if (posParentElement != "" && element.ParentNode.Name != posParentElement) |
132 |
{ |
133 |
continue; |
134 |
} |
135 |
XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); |
136 |
|
137 |
for(int i=0; i<myXmlSubValues.myValues.Count; i++){ |
138 |
//Found a match with the old value? |
139 |
if (myXmlSubValues.myValues[i] == oldValue) |
140 |
{ |
141 |
//replace with the new match |
142 |
myXmlSubValues.myValues[i] = newValue; |
143 |
} |
144 |
} |
145 |
element.InnerText = myXmlSubValues.ToString(); |
146 |
} |
147 |
} |
148 |
|
149 |
saveXmlFile(file); |
150 |
} |
151 |
|
152 |
/// <summary> |
153 |
/// Remove values in an element |
154 |
/// </summary> |
155 |
/// <param name="file"></param> |
156 |
/// <param name="value"></param> |
157 |
public void removeValues(string file, string values) |
158 |
{ |
159 |
Util.backupFile(file); |
160 |
loadXmlFile(file); |
161 |
|
162 |
XmlTextValue myInputValues = new XmlTextValue(values); |
163 |
|
164 |
List<XmlNode> myElements = new List<XmlNode>(); |
165 |
Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element |
166 |
|
167 |
foreach (XmlNode element in myElements) |
168 |
{ |
169 |
if (element.Name == posElement) |
170 |
{ |
171 |
if (posParentElement != "" && element.ParentNode.Name != posParentElement) |
172 |
{ |
173 |
continue; |
174 |
} |
175 |
XmlTextValue myXmlSubValues = new XmlTextValue(element.InnerText); |
176 |
|
177 |
foreach (String myInputValue in myInputValues.myValues) |
178 |
{ |
179 |
for(int i=0; i<myXmlSubValues.myValues.Count; i++){ |
180 |
//It already exists in the xml? |
181 |
if (myInputValue == myXmlSubValues.myValues[i]) |
182 |
{ |
183 |
//remove it |
184 |
myXmlSubValues.myValues.RemoveAt(i); |
185 |
break; |
186 |
} |
187 |
} |
188 |
} |
189 |
element.InnerText = myXmlSubValues.myValues.ToString(); |
190 |
} |
191 |
} |
192 |
|
193 |
saveXmlFile(file); |
194 |
} |
195 |
|
196 |
/// <summary> |
197 |
/// Change a value of element (updating all the chain) |
198 |
/// </summary> |
199 |
/// <param name="file"></param> |
200 |
/// <param name="newValue"></param> |
201 |
/// <param name="valueRelation"></param> |
202 |
public void changeValue(string file, string newValue, string valueRelation = "", string valuePositions = "") |
203 |
{ |
204 |
Util.backupFile(file); |
205 |
loadXmlFile(file); |
206 |
|
207 |
XmlNumberValue xmlLastPos = null, newXmlLastPos = null; |
208 |
|
209 |
List<XmlNode> myElements = new List<XmlNode>(); |
210 |
Util.getAllSpecificElements(xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); //Returns all after "Oni" element |
211 |
|
212 |
if (valuePositions == "") |
213 |
{ |
214 |
newXmlLastPos = new XmlNumberValue(newValue); |
215 |
} |
216 |
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 |
217 |
{ |
218 |
newXmlLastPos = new XmlNumberValue(replaceSpecificPositions(myElements[0].InnerText, newValue, valuePositions)); |
219 |
} |
220 |
|
221 |
if (valuePositions != "") |
222 |
{ |
223 |
checkValidSpecificPositions(valuePositions, newValue, myElements[0].InnerText); |
224 |
} |
225 |
|
226 |
foreach (XmlNode element in myElements) |
227 |
{ |
228 |
if (element.Name == this.posElement && (this.posParentElement == "" || this.posParentElement == element.ParentNode.Name)) |
229 |
{ |
230 |
XmlNumberValue xmlCurrValue = new XmlNumberValue(element.InnerText); |
231 |
|
232 |
if (xmlLastPos != null) |
233 |
{ |
234 |
newXmlLastPos = XmlNumberValue.sum(newXmlLastPos, XmlNumberValue.difference(xmlCurrValue, xmlLastPos)); |
235 |
element.InnerText = newXmlLastPos.ToString(); |
236 |
xmlLastPos = xmlCurrValue; |
237 |
} |
238 |
else |
239 |
{ // first time just assign to last value |
240 |
if (valueRelation != "") |
241 |
{ |
242 |
newXmlLastPos = XmlNumberValue.difference(newXmlLastPos, XmlNumberValue.difference(new XmlNumberValue(valueRelation), xmlCurrValue)); |
243 |
} |
244 |
xmlLastPos = xmlCurrValue; |
245 |
element.InnerText = newXmlLastPos.ToString(); |
246 |
} |
247 |
} |
248 |
} |
249 |
saveXmlFile(file); |
250 |
} |
251 |
|
252 |
/// <summary> |
253 |
/// Invert the values of a element name (inverts all the chain) |
254 |
/// </summary> |
255 |
/// <param name="file"></param> |
256 |
public void invert(string file) |
257 |
{ |
258 |
Util.backupFile(file); |
259 |
loadXmlFile(file); |
260 |
|
261 |
//Inverting the element order |
262 |
List<String> invertedOrder = new List<String>(); |
263 |
|
264 |
List<XmlNode> myElements = new List<XmlNode>(); |
265 |
Util.getAllSpecificElements(this.xdoc.DocumentElement, ref myElements, this.posElement, this.posParentElement); |
266 |
//Read all and save to the list |
267 |
foreach (XmlNode element in myElements) //Returns all after "Oni" element |
268 |
{ |
269 |
invertedOrder.Add(element.InnerText); |
270 |
} |
271 |
|
272 |
//Let's start taking from the list to new xml file (inverted order) |
273 |
|
274 |
int count = 0; |
275 |
|
276 |
foreach (XmlNode element in myElements) //Returns all after "Oni" element |
277 |
{ |
278 |
if (element.Name == posElement) |
279 |
{ |
280 |
element.InnerText = invertedOrder[invertedOrder.Count - 1 - count]; |
281 |
count++; |
282 |
} |
283 |
} |
284 |
saveXmlFile(file); |
285 |
} |
286 |
|
287 |
private void loadXmlFile(string file) |
288 |
{ |
289 |
this.xdoc = new XmlDocument(); |
290 |
this.xdoc.Load(file); |
291 |
} |
292 |
|
293 |
private void saveXmlFile(string file) |
294 |
{ |
295 |
this.xdoc.Save(file); |
296 |
} |
297 |
|
298 |
private void checkValidSpecificPositions(string valuePositions, string value, string firstElement) |
299 |
{ |
300 |
XmlNumberValue testValuePositions = new XmlNumberValue(valuePositions); |
301 |
XmlNumberValue testValue = new XmlNumberValue(value); |
302 |
XmlNumberValue testFirstRealValue = new XmlNumberValue(firstElement); |
303 |
|
304 |
if (testValuePositions.myValues.Count != testValue.myValues.Count) //Check if there are the same number of positions for the same number of dimensions to replace |
305 |
{ |
306 |
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); |
307 |
} |
308 |
foreach (int pos in testValuePositions.myValues) //converts automatically from double to int |
309 |
{ |
310 |
if (pos > testFirstRealValue.myValues.Count - 1 || pos < 0) //Are positions valid for the current values? //-1 because starts at 0 |
311 |
{ |
312 |
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); |
313 |
} |
314 |
} |
315 |
} |
316 |
|
317 |
private string replaceSpecificPositions(string currXmlValue, string values, string valuePositions) |
318 |
{ |
319 |
XmlNumberValue currentValue = new XmlNumberValue(currXmlValue); |
320 |
XmlNumberValue positionsValues = new XmlNumberValue(valuePositions); |
321 |
XmlNumberValue newValues = new XmlNumberValue(values); |
322 |
|
323 |
for (int i = 0; i < positionsValues.myValues.Count; i++) |
324 |
{ |
325 |
int posToChange = (int)positionsValues.myValues[i]; |
326 |
currentValue.myValues[posToChange] = newValues.myValues[i]; |
327 |
} |
328 |
|
329 |
return currentValue.ToString(); |
330 |
} |
331 |
} |
332 |
} |