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