source: xmlTools/trunk/posUpdate/XmlTools.cs@ 861

Last change on this file since 861 was 861, checked in by s10k, 12 years ago

xmlTools: v0.8e, fixed a bug reported by EdT:

mono xmlTools.exe updatechainvalues -filename:OBANheli_body_center.xml -newvalue:"20 10 30" -element:Translation -parelement:OBANKeyFrame

I get the error: Object reference not set to an instance of an object

also fixed a bit the documentation o updatechainvalues command

File size: 13.8 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Xml;
5
6namespace 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 (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 (posParentElement != "" && element.ParentNode.Name != posParentElement)
53 {
54 continue;
55 }
56 if (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 (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 (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 (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 (valuePositions == null)
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 (valuePositions != null)
242 {
243 checkValidSpecificPositions(valuePositions, newValue, myElements[0].InnerText);
244 }
245
246 foreach (XmlNode element in myElements)
247 {
248 if (element.Name == this.posElement && (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 (valueRelation != null)
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}
Note: See TracBrowser for help on using the repository browser.