source: XmlTools2/trunk/XmlTools/xmltools.cpp@ 905

Last change on this file since 905 was 905, checked in by s10k, 11 years ago

XmlTools v2

File size: 10.8 KB
Line 
1#include "xmltools.h"
2
3XmlTools::XmlTools(QString filesWildcard, XmlFilter filter, bool noBackups)
4{
5 this->filesToProcess=UtilXmlTools::getAllXmlFilesByWildcard(filesWildcard);
6 this->filters=filter;
7 this->backupsEnabled=!noBackups;
8
9 if(this->filesToProcess.size()==0){
10 UtilXmlTools::displayErrorMessage("Loading xml files","No XML files were found for the wildcard: "+filesWildcard);
11 }
12}
13
14// Adds new values to an element
15void XmlTools::addValues(QString newValues){
16
17 // Process all XmlFiles
18 for(int i=0; i<this->filesToProcess.size(); i++){
19
20 QStringList newValuesList, currValuesList;
21 QList<pugi::xml_node> elements;
22
23 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled,"add-values");
24
25 newValuesList=Util::qStringListFromSpacedString(newValues);
26 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
27
28 for(int j=0; j<elements.size(); j++){
29
30 currValuesList=Util::qStringListFromSpacedString(Util::toQString(elements[j].text().as_string())); // convert each element in a list (uses space as separator)
31
32 for(int k=0; k<newValuesList.size(); k++){
33 if(currValuesList.contains(newValuesList[k])){ // If the current element already contains this value proceed to the next
34 continue;
35 }
36
37 elements[j].text()=QString(Util::toQString(elements[j].text().as_string()) + " " + newValuesList[k]).toLatin1().constData(); // If it doesn't exists yet let's add it
38 }
39 }
40
41 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document,"add-values");
42 }
43
44 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(), "add-values");
45
46}
47
48void XmlTools::removeValues(QString valuesToRemove){
49
50 // Process all XmlFiles
51 for(int i=0; i<this->filesToProcess.size(); i++){
52
53 QList<pugi::xml_node> elements;
54 QStringList valuesToRemoveList, currValuesList;
55 bool elementChanged=false;
56
57 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled, "remove-values");
58
59 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
60
61 valuesToRemoveList=Util::qStringListFromSpacedString(valuesToRemove);
62
63 for(int j=0; j<elements.size(); j++){ // O(3)... Optimization may be necessary.
64 currValuesList=Util::qStringListFromSpacedString(Util::toQString(elements[j].text().as_string())); // convert each element in a list (uses space as separator)
65
66 for(int k=0; k<currValuesList.size(); k++){
67 for(int m=0; m<valuesToRemoveList.size(); m++){
68 if(currValuesList[k]==valuesToRemoveList[m]){
69 currValuesList[k]=""; // remove it
70 elementChanged=true;
71 }
72 }
73 }
74
75 if(elementChanged){ // If curr element changed update the XML
76 elements[j].text()=currValuesList.join(' ').toLatin1().constData();
77 elementChanged=false;
78 }
79 }
80
81 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document, "remove-values");
82 }
83
84
85 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(),"remove-values");
86}
87
88void XmlTools::replaceValue(QString oldValue, QString newValue){
89
90 // Process all XmlFiles
91 for(int i=0; i<this->filesToProcess.size(); i++){
92
93 QList<pugi::xml_node> elements;
94 QStringList currValuesList;
95 bool elementChanged=false;
96
97 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled, "replace-value");
98
99 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
100
101 for(int j=0; j<elements.size(); j++){
102 currValuesList=Util::qStringListFromSpacedString(Util::toQString(elements[j].text().as_string())); // convert each element in a list (uses space as separator)
103
104 for(int k=0; k<currValuesList.size(); k++){
105 if(currValuesList[k]==oldValue){ // Found a match with the old value?
106 currValuesList[k]=newValue; // If found replace it with the new value
107 elementChanged=true;
108 }
109 }
110
111 if(elementChanged){ // If curr element changed update the XML
112 elements[j].text()=currValuesList.join(" ").toLatin1().constData();
113 }
114 elementChanged=false;
115 }
116
117 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document, "replace-value");
118 }
119
120 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(), "replace-value");
121}
122
123// Replaces all current values of an element by another (can be specified only specific positions)
124void XmlTools::replaceAll(QString value, QString valuePositions){
125
126 // Process all XmlFiles
127 for(int i=0; i<this->filesToProcess.size(); i++){
128
129 QList<pugi::xml_node> elements;
130
131 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled, "replace-all");
132
133 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
134
135
136 // Let's start the override
137 for(int j=0; j<elements.size(); j++){
138 if(valuePositions!=""){
139 elements[j].text()=replaceSpecificPositions(value, Util::toQString(elements[j].text().as_string()),valuePositions).toLatin1().constData();
140 }
141 else{
142 elements[j].text()=value.toLatin1().constData();
143 }
144 }
145
146 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document, "replace-all");
147 }
148
149 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(), "replace-all");
150}
151
152// Update a set of XML elements values based in the difference between the old and new value
153// This can be used in multiple files if the difference between one file and other are the same e.g. increment to all current object positions 100 in y (A difference of -100).
154// E.g. oldValue=5 , newValue=7; diffBetweenOldAndNewValue=-2
155void XmlTools::updateElements(QString diffBetweenOldAndNewValue){
156
157 // Process all XmlFiles
158 for(int i=0; i<this->filesToProcess.size(); i++){
159
160 QList<pugi::xml_node> elements;
161 MultiDimVar lastXmlValue(0); // inicialize with any value or dimension
162 MultiDimVar currXmlValue(0);
163 MultiDimVar newXmlValue(0); // value that will update currValue
164
165 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled, "update-elements");
166
167 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
168
169
170 if(elements.size()>1){
171 lastXmlValue=MultiDimVar(Util::toQString(elements[0].text().as_string())); // the lastXmlValue will begin to be the first one of the node
172 currXmlValue=MultiDimVar(Util::toQString(elements[1].text().as_string())); // the currXmlValue will begin to be the second one of the node
173 newXmlValue=MultiDimVar::sub(lastXmlValue, MultiDimVar(diffBetweenOldAndNewValue));
174 elements[0].text() = newXmlValue.toString().toLatin1().constData(); // update the first eblement with the new one already
175 }
176
177 // Let's start the node update
178 for(int j=1; j<elements.size()-1; j++){ // We start in 1 because the 0 is already saved in lastXmlValue // -1 because we will also work with the next one in the current
179
180 newXmlValue=MultiDimVar::sum(newXmlValue,MultiDimVar::sub(currXmlValue,lastXmlValue));
181 elements[j].text() = newXmlValue.toString().toLatin1().constData(); // update element with the new value
182 lastXmlValue=currXmlValue;
183 currXmlValue=MultiDimVar(Util::toQString(elements[j+1].text().as_string()));
184
185 }
186
187 // To update too last element (avoid out of bound because i+1)
188 newXmlValue=MultiDimVar::sum(newXmlValue,MultiDimVar::sub(currXmlValue,lastXmlValue));
189 elements[elements.size()-1].text() = newXmlValue.toString().toLatin1().constData(); // update element with the new value
190
191 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document, "update-elements");
192 }
193
194 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(),"updateNode");
195
196}
197
198// Invert a set of XML elements with specified name (and optionally a parent name)
199void XmlTools::invertElements(){
200
201 // Process all XmlFiles
202 for(int i=0; i<this->filesToProcess.size(); i++){
203 UtilXmlTools::loadXmlFile(this->filesToProcess[i],this->document,this->rootNode,this->backupsEnabled, "invert-elements");
204
205 QList<pugi::xml_node> elements;
206 QStringList invertedElements; //Inverting the element order
207
208 UtilXmlTools::getAllNamedElements(this->rootNode,elements,this->filters);
209
210 // Read all elements and save to the list
211 for(int j=elements.size()-1; j>=0; j--){
212 invertedElements << Util::toQString(elements[j].text().as_string());
213 }
214
215 // Override the tree with the inverted order
216 for(int j=0; j<elements.size(); j++){
217 elements[j].text()= invertedElements[j].toLatin1().constData();
218 }
219
220 UtilXmlTools::saveXmlFile(this->filesToProcess[i],this->document, "invert-elements");
221 }
222
223 UtilXmlTools::displaySuccessMessage(this->filesToProcess.size(),"invert-elements");
224
225}
226
227// Replaces specific values (given the position) for a new value
228// [ currValues / positionsToReplaced are strings with composed by another strings space separated ]
229// Returns a new string (space separated) will values replaced
230QString XmlTools::replaceSpecificPositions(const QString &newValue, const QString &currValues, const QString &positionsToReplace){
231
232 QList<int> positionsToReplaceList;
233 QStringList currValuesList;
234
235 positionsToReplaceList=Util::qListIntFromSpacedString(positionsToReplace);
236 currValuesList=Util::qStringListFromSpacedString(currValues);
237
238 // Make some validation before the replacing
239 if(currValuesList.size()<positionsToReplaceList.size()){
240 UtilXmlTools::displayErrorMessage("replaceSpecificPositions","There are more positions to replace than the current xml values.");
241 }
242
243 foreach(int pos, positionsToReplaceList){
244 if(pos>currValuesList.size()-1 || pos < 0){ //Are positions valid for the current values? //-1 because starts at 0
245 UtilXmlTools::displayErrorMessage("replaceSpecificPositions","One or more of the specified positions to replace are out of range.");
246 }
247 }
248 //
249
250 // Finally replace the specified values
251 foreach(int pos, positionsToReplaceList){
252 currValuesList[pos]=newValue;
253 }
254
255 return currValuesList.join(" ");
256
257}
Note: See TracBrowser for help on using the repository browser.