]> git.mxchange.org Git - flightgear.git/blob - src/FDM/JSBSim/input_output/FGXMLElement.cpp
remove unused files
[flightgear.git] / src / FDM / JSBSim / input_output / FGXMLElement.cpp
1 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2
3  Author:       Jon Berndt
4  Date started: 09/28/2004
5  Purpose:      XML element class
6  Called by:    FGXMLParse
7
8  ------------- Copyright (C) 2001  Jon S. Berndt (jon@jsbsim.org) -------------
9
10  This program is free software; you can redistribute it and/or modify it under
11  the terms of the GNU Lesser General Public License as published by the Free Software
12  Foundation; either version 2 of the License, or (at your option) any later
13  version.
14
15  This program is distributed in the hope that it will be useful, but WITHOUT
16  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17  FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
18  details.
19
20  You should have received a copy of the GNU Lesser General Public License along with
21  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
22  Place - Suite 330, Boston, MA  02111-1307, USA.
23
24  Further information about the GNU Lesser General Public License can also be found on
25  the world wide web at http://www.gnu.org.
26
27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28 INCLUDES
29 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
30
31 #include "FGXMLElement.h"
32
33 #include <cmath>
34 #include <cstdlib>
35 #include <iostream>
36
37 using namespace std;
38
39 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 FORWARD DECLARATIONS
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
42
43 namespace JSBSim {
44
45 static const char *IdSrc = "$Id: FGXMLElement.cpp,v 1.33 2011/08/05 12:28:20 jberndt Exp $";
46 static const char *IdHdr = ID_XMLELEMENT;
47
48 bool Element::converterIsInitialized = false;
49 map <string, map <string, double> > Element::convert;
50
51 /*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52 CLASS IMPLEMENTATION
53 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
54
55 Element::Element(const string& nm)
56 {
57   name   = nm;
58   parent = 0L;
59   element_index = 0;
60
61   if (!converterIsInitialized) {
62     converterIsInitialized = true;
63     // convert ["from"]["to"] = factor, so: from * factor = to
64     // Length
65     convert["M"]["FT"] = 3.2808399;
66     convert["FT"]["M"] = 1.0/convert["M"]["FT"];
67     convert["CM"]["FT"] = 0.032808399;
68     convert["FT"]["CM"] = 1.0/convert["CM"]["FT"];
69     convert["KM"]["FT"] = 3280.8399;
70     convert["FT"]["KM"] = 1.0/convert["KM"]["FT"];
71     convert["FT"]["IN"] = 12.0;
72     convert["IN"]["FT"] = 1.0/convert["FT"]["IN"];
73     convert["IN"]["M"] = convert["IN"]["FT"] * convert["FT"]["M"];
74     convert["M"]["IN"] = convert["M"]["FT"] * convert["FT"]["IN"];
75     // Area
76     convert["M2"]["FT2"] = convert["M"]["FT"]*convert["M"]["FT"];
77     convert["FT2"]["M2"] = 1.0/convert["M2"]["FT2"];
78     convert["CM2"]["FT2"] = convert["CM"]["FT"]*convert["CM"]["FT"];
79     convert["FT2"]["CM2"] = 1.0/convert["CM2"]["FT2"];
80     convert["M2"]["IN2"] = convert["M"]["IN"]*convert["M"]["IN"];
81     convert["IN2"]["M2"] = 1.0/convert["M2"]["IN2"];
82     convert["FT2"]["IN2"] = 144.0;
83     convert["IN2"]["FT2"] = 1.0/convert["FT2"]["IN2"];
84     // Volume
85     convert["IN3"]["CC"] = 16.387064;
86     convert["CC"]["IN3"] = 1.0/convert["IN3"]["CC"];
87     convert["FT3"]["IN3"] = 1728.0;
88     convert["IN3"]["FT3"] = 1.0/convert["FT3"]["IN3"];
89     convert["M3"]["FT3"] = 35.3146667;
90     convert["FT3"]["M3"] = 1.0/convert["M3"]["FT3"];
91     convert["LTR"]["IN3"] = 61.0237441;
92     convert["IN3"]["LTR"] = 1.0/convert["LTR"]["IN3"];
93     // Mass & Weight
94     convert["LBS"]["KG"] = 0.45359237;
95     convert["KG"]["LBS"] = 1.0/convert["LBS"]["KG"];
96     convert["SLUG"]["KG"] = 14.59390;
97     convert["KG"]["SLUG"] = 1.0/convert["SLUG"]["KG"];
98     // Moments of Inertia
99     convert["SLUG*FT2"]["KG*M2"] = 1.35594;
100     convert["KG*M2"]["SLUG*FT2"] = 1.0/convert["SLUG*FT2"]["KG*M2"];
101     // Angles
102     convert["RAD"]["DEG"] = 180.0/M_PI;
103     convert["DEG"]["RAD"] = 1.0/convert["RAD"]["DEG"];
104     // Angular rates
105     convert["RAD/SEC"]["DEG/SEC"] = convert["RAD"]["DEG"];
106     convert["DEG/SEC"]["RAD/SEC"] = 1.0/convert["RAD/SEC"]["DEG/SEC"];
107     // Spring force
108     convert["LBS/FT"]["N/M"] = 14.5939;
109     convert["N/M"]["LBS/FT"] = 1.0/convert["LBS/FT"]["N/M"];
110     // Damping force
111     convert["LBS/FT/SEC"]["N/M/SEC"] = 14.5939;
112     convert["N/M/SEC"]["LBS/FT/SEC"] = 1.0/convert["LBS/FT/SEC"]["N/M/SEC"];
113     // Damping force (Square Law)
114     convert["LBS/FT2/SEC2"]["N/M2/SEC2"] = 47.880259;
115     convert["N/M2/SEC2"]["LBS/FT2/SEC2"] = 1.0/convert["LBS/FT2/SEC2"]["N/M2/SEC2"];
116     // Power
117     convert["WATTS"]["HP"] = 0.001341022;
118     convert["HP"]["WATTS"] = 1.0/convert["WATTS"]["HP"];
119     // Force
120     convert["N"]["LBS"] = 0.22482;
121     convert["LBS"]["N"] = 1.0/convert["N"]["LBS"];
122     // Velocity
123     convert["KTS"]["FT/SEC"] = 1.68781;
124     convert["FT/SEC"]["KTS"] = 1.0/convert["KTS"]["FT/SEC"];
125     convert["M/S"]["FT/S"] = 3.2808399;
126     convert["M/SEC"]["FT/SEC"] = 3.2808399;
127     convert["FT/S"]["M/S"] = 1.0/convert["M/S"]["FT/S"];
128     convert["M/SEC"]["FT/SEC"] = 3.2808399;
129     convert["FT/SEC"]["M/SEC"] = 1.0/convert["M/SEC"]["FT/SEC"];
130     convert["KM/SEC"]["FT/SEC"] = 3280.8399;
131     convert["FT/SEC"]["KM/SEC"] = 1.0/convert["KM/SEC"]["FT/SEC"];
132     // Torque
133     convert["FT*LBS"]["N*M"] = 1.35581795;
134     convert["N*M"]["FT*LBS"] = 1/convert["FT*LBS"]["N*M"];
135     // Valve
136     convert["M4*SEC/KG"]["FT4*SEC/SLUG"] = convert["M"]["FT"]*convert["M"]["FT"]*
137       convert["M"]["FT"]*convert["M"]["FT"]/convert["KG"]["SLUG"];
138     convert["FT4*SEC/SLUG"]["M4*SEC/KG"] =
139       1.0/convert["M4*SEC/KG"]["FT4*SEC/SLUG"];
140     // Pressure
141     convert["INHG"]["PSF"] = 70.7180803;
142     convert["PSF"]["INHG"] = 1.0/convert["INHG"]["PSF"];
143     convert["ATM"]["INHG"] = 29.9246899;
144     convert["INHG"]["ATM"] = 1.0/convert["ATM"]["INHG"];
145     convert["PSI"]["INHG"] = 2.03625437;
146     convert["INHG"]["PSI"] = 1.0/convert["PSI"]["INHG"];
147     convert["INHG"]["PA"] = 3386.0; // inches Mercury to pascals
148     convert["PA"]["INHG"] = 1.0/convert["INHG"]["PA"];
149     convert["LBS/FT2"]["N/M2"] = 14.5939/convert["FT"]["M"];
150     convert["N/M2"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["N/M2"];
151     convert["LBS/FT2"]["PA"] = convert["LBS/FT2"]["N/M2"];
152     convert["PA"]["LBS/FT2"] = 1.0/convert["LBS/FT2"]["PA"];
153     // Mass flow
154     convert["KG/MIN"]["LBS/MIN"] = convert["KG"]["LBS"];
155     // Fuel Consumption
156     convert["LBS/HP*HR"]["KG/KW*HR"] = 0.6083;
157     convert["KG/KW*HR"]["LBS/HP*HR"] = 1.0/convert["LBS/HP*HR"]["KG/KW*HR"];
158     // Density
159     convert["KG/L"]["LBS/GAL"] = 8.3454045;
160     convert["LBS/GAL"]["KG/L"] = 1.0/convert["KG/L"]["LBS/GAL"];
161
162     // Length
163     convert["M"]["M"] = 1.00;
164     convert["KM"]["KM"] = 1.00;
165     convert["FT"]["FT"] = 1.00;
166     convert["IN"]["IN"] = 1.00;
167     // Area
168     convert["M2"]["M2"] = 1.00;
169     convert["FT2"]["FT2"] = 1.00;
170     // Volume
171     convert["IN3"]["IN3"] = 1.00;
172     convert["CC"]["CC"] = 1.0;
173     convert["M3"]["M3"] = 1.0;
174     convert["FT3"]["FT3"] = 1.0;
175     convert["LTR"]["LTR"] = 1.0;
176     // Mass & Weight
177     convert["KG"]["KG"] = 1.00;
178     convert["LBS"]["LBS"] = 1.00;
179     // Moments of Inertia
180     convert["KG*M2"]["KG*M2"] = 1.00;
181     convert["SLUG*FT2"]["SLUG*FT2"] = 1.00;
182     // Angles
183     convert["DEG"]["DEG"] = 1.00;
184     convert["RAD"]["RAD"] = 1.00;
185     // Angular rates
186     convert["DEG/SEC"]["DEG/SEC"] = 1.00;
187     convert["RAD/SEC"]["RAD/SEC"] = 1.00;
188     // Spring force
189     convert["LBS/FT"]["LBS/FT"] = 1.00;
190     convert["N/M"]["N/M"] = 1.00;
191     // Damping force
192     convert["LBS/FT/SEC"]["LBS/FT/SEC"] = 1.00;
193     convert["N/M/SEC"]["N/M/SEC"] = 1.00;
194     // Damping force (Square law)
195     convert["LBS/FT2/SEC2"]["LBS/FT2/SEC2"] = 1.00;
196     convert["N/M2/SEC2"]["N/M2/SEC2"] = 1.00;
197     // Power
198     convert["HP"]["HP"] = 1.00;
199     convert["WATTS"]["WATTS"] = 1.00;
200     // Force
201     convert["N"]["N"] = 1.00;
202     // Velocity
203     convert["FT/SEC"]["FT/SEC"] = 1.00;
204     convert["KTS"]["KTS"] = 1.00;
205     convert["M/S"]["M/S"] = 1.0;
206     convert["M/SEC"]["M/SEC"] = 1.0;
207     convert["KM/SEC"]["KM/SEC"] = 1.0;
208     // Torque
209     convert["FT*LBS"]["FT*LBS"] = 1.00;
210     convert["N*M"]["N*M"] = 1.00;
211     // Valve
212     convert["M4*SEC/KG"]["M4*SEC/KG"] = 1.0;
213     convert["FT4*SEC/SLUG"]["FT4*SEC/SLUG"] = 1.0;
214     // Pressure
215     convert["PSI"]["PSI"] = 1.00;
216     convert["PSF"]["PSF"] = 1.00;
217     convert["INHG"]["INHG"] = 1.00;
218     convert["ATM"]["ATM"] = 1.0;
219     convert["PA"]["PA"] = 1.0;
220     convert["N/M2"]["N/M2"] = 1.00;
221     convert["LBS/FT2"]["LBS/FT2"] = 1.00;
222     // Mass flow
223     convert["LBS/SEC"]["LBS/SEC"] = 1.00;
224     convert["KG/MIN"]["KG/MIN"] = 1.0;
225     convert["LBS/MIN"]["LBS/MIN"] = 1.0;
226     // Fuel Consumption
227     convert["LBS/HP*HR"]["LBS/HP*HR"] = 1.0;
228     convert["KG/KW*HR"]["KG/KW*HR"] = 1.0;
229     // Density
230     convert["KG/L"]["KG/L"] = 1.0;
231     convert["LBS/GAL"]["LBS/GAL"] = 1.0;
232   }
233 }
234
235 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236
237 Element::~Element(void)
238 {
239   for (unsigned int i=0; i<children.size(); i++) delete children[i];
240   data_lines.clear();
241   attributes.clear();
242   attribute_key.clear();
243 }
244
245 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246
247 string Element::GetAttributeValue(const string& attr)
248 {
249   int select=-1;
250   for (unsigned int i=0; i<attribute_key.size(); i++) {
251     if (attribute_key[i] == attr) select = i;
252   }
253   if (select < 0) return string("");
254   else return attributes[attr];
255 }
256
257 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258
259 double Element::GetAttributeValueAsNumber(const string& attr)
260 {
261   string attribute = GetAttributeValue(attr);
262
263   if (attribute.empty()) return HUGE_VAL;
264   else return (atof(attribute.c_str()));
265 }
266
267 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
268
269 Element* Element::GetElement(unsigned int el)
270 {
271   if (children.size() > el) {
272     element_index = el;
273     return children[el];
274   }
275   else {
276     element_index = 0;
277     return 0L;
278   }
279 }
280
281 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282
283 Element* Element::GetNextElement(void)
284 {
285   if (children.size() > element_index+1) {
286     element_index++;
287     return children[element_index];
288   } else {
289     element_index = 0;
290     return 0L;
291   }
292 }
293
294 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
295
296 string Element::GetDataLine(unsigned int i)
297 {
298   if (data_lines.size() > 0) return data_lines[i];
299   else return string("");
300 }
301
302 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303
304 double Element::GetDataAsNumber(void)
305 {
306   if (data_lines.size() == 1) {
307     return atof(data_lines[0].c_str());
308   } else if (data_lines.size() == 0) {
309     return HUGE_VAL;
310   } else {
311     cerr << "Attempting to get single data value from multiple lines in element " << name << endl;
312     return HUGE_VAL;
313   }
314 }
315
316 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317
318 unsigned int Element::GetNumElements(const string& element_name)
319 {
320   unsigned int number_of_elements=0;
321   Element* el=FindElement(element_name);
322   while (el) {
323     number_of_elements++;
324     el=FindNextElement(element_name);
325   }
326   return number_of_elements;
327 }
328
329 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330
331 Element* Element::FindElement(const string& el)
332 {
333   if (el.empty() && children.size() >= 1) {
334     element_index = 1;
335     return children[0];
336   }
337   for (unsigned int i=0; i<children.size(); i++) {
338     if (el == children[i]->GetName()) {
339       element_index = i+1;
340       return children[i];
341     }
342   }
343   element_index = 0;
344   return 0L;
345 }
346
347 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348
349 Element* Element::FindNextElement(const string& el)
350 {
351   if (el.empty()) {
352     if (element_index < children.size()) {
353       return children[element_index++];
354     } else {
355       element_index = 0;
356       return 0L;
357     }
358   }
359   for (unsigned int i=element_index; i<children.size(); i++) {
360     if (el == children[i]->GetName()) {
361       element_index = i+1;
362       return children[i];
363     }
364   }
365   element_index = 0;
366   return 0L;
367 }
368
369 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370
371 double Element::FindElementValueAsNumber(const string& el)
372 {
373   Element* element = FindElement(el);
374   if (element) {
375     return element->GetDataAsNumber();
376   } else {
377     cerr << "Attempting to get single data value from multiple lines" << endl;
378     return 0;
379   }
380 }
381
382 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383
384 string Element::FindElementValue(const string& el)
385 {
386   Element* element = FindElement(el);
387   if (element) {
388     return element->GetDataLine();
389   } else {
390     return "";
391   }
392 }
393
394 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395
396 double Element::FindElementValueAsNumberConvertTo(const string& el, const string& target_units)
397 {
398   Element* element = FindElement(el);
399
400   if (!element) {
401     cerr << "Attempting to get non-existent element " << el << endl;
402     exit(0);
403   }
404
405   string supplied_units = element->GetAttributeValue("unit");
406
407   if (!supplied_units.empty()) {
408     if (convert.find(supplied_units) == convert.end()) {
409       cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
410            << " conversion in FGXMLElement.cpp." << endl;
411       exit(-1);
412     }
413     if (convert[supplied_units].find(target_units) == convert[supplied_units].end()) {
414       cerr << endl << "Supplied unit: \"" << supplied_units << "\" cannot be converted to "
415                    << target_units << ". Add new unit conversion in FGXMLElement.cpp or fix typo" << endl;
416       exit(-1);
417     }
418   }
419
420   double value = element->GetDataAsNumber();
421   if (!supplied_units.empty()) {
422     value *= convert[supplied_units][target_units];
423   }
424
425   return value;
426 }
427
428 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
429
430 double Element::FindElementValueAsNumberConvertFromTo( const string& el,
431                                                        const string& supplied_units,
432                                                        const string& target_units)
433 {
434   Element* element = FindElement(el);
435
436   if (!element) {
437     cerr << "Attempting to get non-existent element " << el << endl;
438     exit(0);
439   }
440
441   if (!supplied_units.empty()) {
442     if (convert.find(supplied_units) == convert.end()) {
443       cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
444            << " conversion in FGXMLElement.cpp." << endl;
445       exit(-1);
446     }
447     if (convert[supplied_units].find(target_units) == convert[supplied_units].end()) {
448       cerr << endl << "Supplied unit: \"" << supplied_units << "\" cannot be converted to "
449                    << target_units << ". Add new unit conversion in FGXMLElement.cpp or fix typo" << endl;
450       exit(-1);
451     }
452   }
453
454   double value = element->GetDataAsNumber();
455   if (!supplied_units.empty()) {
456     value *= convert[supplied_units][target_units];
457   }
458
459   return value;
460 }
461
462 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
463
464 FGColumnVector3 Element::FindElementTripletConvertTo( const string& target_units)
465 {
466   FGColumnVector3 triplet;
467   Element* item;
468   double value=0.0;
469   string supplied_units = GetAttributeValue("unit");
470
471   if (!supplied_units.empty()) {
472     if (convert.find(supplied_units) == convert.end()) {
473       cerr << endl << "Supplied unit: \"" << supplied_units << "\" does not exist (typo?). Add new unit"
474            << " conversion in FGXMLElement.cpp." << endl;
475       exit(-1);
476     }
477     if (convert[supplied_units].find(target_units) == convert[supplied_units].end()) {
478       cerr << endl << "Supplied unit: \"" << supplied_units << "\" cannot be converted to "
479                    << target_units << ". Add new unit conversion in FGXMLElement.cpp or fix typo" << endl;
480       exit(-1);
481     }
482   }
483
484   item = FindElement("x");
485   if (!item) item = FindElement("roll");
486   if (item) {
487     value = item->GetDataAsNumber();
488     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
489   } else {
490     value = 0.0;
491   }
492   triplet(1) = value;
493
494   item = FindElement("y");
495   if (!item) item = FindElement("pitch");
496   if (item) {
497     value = item->GetDataAsNumber();
498     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
499   } else {
500     value = 0.0;
501   }
502   triplet(2) = value;
503
504   item = FindElement("z");
505   if (!item) item = FindElement("yaw");
506   if (item) {
507     value = item->GetDataAsNumber();
508     if (!supplied_units.empty()) value *= convert[supplied_units][target_units];
509   } else {
510     value = 0.0;
511   }
512   triplet(3) = value;
513
514   return triplet;
515 }
516
517 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518
519 void Element::Print(unsigned int level)
520 {
521   unsigned int i, spaces;
522
523   level+=2;
524   for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
525   cout << "Element Name: " << name;
526   for (i=0; i<attributes.size(); i++) {
527     cout << "  " << attribute_key[i] << " = " << attributes[attribute_key[i]];
528   }
529   cout << endl;
530   for (i=0; i<data_lines.size(); i++) {
531     for (spaces=0; spaces<=level; spaces++) cout << " "; // format output
532     cout << data_lines[i] << endl;
533   }
534   for (i=0; i<children.size(); i++) {
535     children[i]->Print(level);
536   }
537 }
538
539 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
540
541 void Element::AddAttribute(const string& name, const string& value)
542 {
543   attribute_key.push_back(name);
544   attributes[name] = value;
545 }
546
547 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
548
549 void Element::AddData(string d)
550 {
551   string::size_type string_start = d.find_first_not_of(" \t");
552   if (string_start != string::npos && string_start > 0) {
553     d.erase(0,string_start);
554   }
555   data_lines.push_back(d);
556 }
557
558 //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559
560 } // end namespace JSBSim