]> SALOME platform Git repositories - modules/geom.git/blob - src/XAO/XAO_XaoExporter.cxx
Salome HOME
Fix a bug that NbShapes() and ShapeInfo() return 2 solids for a box
[modules/geom.git] / src / XAO / XAO_XaoExporter.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Frederic Pons (OpenCascade)
20
21 #include <libxml/parser.h>
22
23 #include "XAO_XaoExporter.hxx"
24 #include "XAO_Xao.hxx"
25 #include "XAO_Geometry.hxx"
26 #include "XAO_Group.hxx"
27 #include "XAO_Field.hxx"
28 #include "XAO_Step.hxx"
29 #include "XAO_XaoUtils.hxx"
30
31 namespace XAO
32 {
33     const xmlChar* C_TAG_XAO = (xmlChar*)"XAO";
34     const xmlChar* C_ATTR_XAO_AUTHOR = (xmlChar*)"author";
35     const xmlChar* C_ATTR_XAO_VERSION = (xmlChar*)"version";
36
37     const xmlChar* C_TAG_GEOMETRY = (xmlChar*)"geometry";
38     const xmlChar* C_ATTR_GEOMETRY_NAME = (xmlChar*)"name";
39
40     const xmlChar* C_TAG_SHAPE = (xmlChar*)"shape";
41     const xmlChar* C_ATTR_SHAPE_FORMAT = (xmlChar*)"format";
42
43     const xmlChar* C_TAG_TOPOLOGY = (xmlChar*)"topology";
44     const xmlChar* C_TAG_VERTICES = (xmlChar*)"vertices";
45     const xmlChar* C_TAG_VERTEX = (xmlChar*)"vertex";
46     const xmlChar* C_TAG_EDGES = (xmlChar*)"edges";
47     const xmlChar* C_TAG_EDGE = (xmlChar*)"edge";
48     const xmlChar* C_TAG_FACES = (xmlChar*)"faces";
49     const xmlChar* C_TAG_FACE = (xmlChar*)"face";
50     const xmlChar* C_TAG_SOLIDS = (xmlChar*)"solids";
51     const xmlChar* C_TAG_SOLID = (xmlChar*)"solid";
52     const xmlChar* C_ATTR_COUNT = (xmlChar*)"count";
53     const xmlChar* C_ATTR_ELT_INDEX = (xmlChar*)"index";
54     const xmlChar* C_ATTR_ELT_NAME = (xmlChar*)"name";
55     const xmlChar* C_ATTR_ELT_REFERENCE = (xmlChar*)"reference";
56
57     const xmlChar* C_TAG_GROUPS = (xmlChar*)"groups";
58     const xmlChar* C_TAG_GROUP = (xmlChar*)"group";
59     const xmlChar* C_ATTR_GROUP_NAME = (xmlChar*)"name";
60     const xmlChar* C_ATTR_GROUP_DIM = (xmlChar*)"dimension";
61
62     const xmlChar* C_TAG_ELEMENT = (xmlChar*)"element";
63     const xmlChar* C_ATTR_ELEMENT_INDEX = (xmlChar*)"index";
64     const xmlChar* C_TAG_VALUE = (xmlChar*)"value";
65     const xmlChar* C_ATTR_VALUE_COMPONENT = (xmlChar*)"component";
66
67     const xmlChar* C_TAG_FIELDS = (xmlChar*)"fields";
68     const xmlChar* C_TAG_FIELD = (xmlChar*)"field";
69     const xmlChar* C_ATTR_FIELD_NAME = (xmlChar*)"name";
70     const xmlChar* C_ATTR_FIELD_TYPE = (xmlChar*)"type";
71     const xmlChar* C_ATTR_FIELD_DIMENSION = (xmlChar*)"dimension";
72     const xmlChar* C_TAG_COMPONENTS = (xmlChar*)"components";
73     const xmlChar* C_TAG_COMPONENT = (xmlChar*)"component";
74     const xmlChar* C_ATTR_COMPONENT_COLUMN = (xmlChar*)"column";
75     const xmlChar* C_ATTR_COMPONENT_NAME = (xmlChar*)"name";
76
77     const xmlChar* C_TAG_STEPS = (xmlChar*)"steps";
78     const xmlChar* C_TAG_STEP = (xmlChar*)"step";
79     const xmlChar* C_ATTR_STEP_NUMBER = (xmlChar*)"number";
80     const xmlChar* C_ATTR_STEP_STAMP = (xmlChar*)"stamp";
81 }
82
83 using namespace XAO;
84
85 std::string XaoExporter::readStringProp(xmlNodePtr node, const xmlChar* attribute,
86         const bool& required, const std::string& defaultValue,
87         const std::string& exception /*= std::string() */)
88 {
89     xmlChar* strAttr = xmlGetProp(node, attribute);
90     if (strAttr == NULL)
91     {
92         if (required)
93         {
94             if (exception.size() > 0)
95                 throw XAO_Exception(exception.c_str());
96
97             throw XAO_Exception(MsgBuilder() << "Line " << node->line << ": "
98                                              << "Property " << (char*)attribute << " is required.");
99         }
100
101         return defaultValue;
102     }
103
104     std::string res = (char*)strAttr;
105     xmlFree(strAttr);
106     return res;
107 }
108
109 int XaoExporter::readIntegerProp(xmlNodePtr node, const xmlChar* attribute,
110         const bool& required, const int& defaultValue,
111         const std::string& exception /*= std::string() */)
112 {
113     xmlChar* strAttr = xmlGetProp(node, attribute);
114     if (strAttr == NULL)
115     {
116         if (required)
117         {
118             if (exception.size() > 0)
119                 throw XAO_Exception(exception.c_str());
120
121             throw XAO_Exception(MsgBuilder() << "Line " << node->line << ": "
122                                              << "Property " << (char*)attribute << " is required.");
123         }
124
125         return defaultValue;
126     }
127
128     int res = XaoUtils::stringToInt((char*)strAttr);
129     xmlFree(strAttr);
130     return res;
131 }
132
133 const bool XaoExporter::saveToFile(Xao* xaoObject, const std::string& fileName)
134 throw (XAO_Exception)
135 {
136     xmlDocPtr doc = exportXMLDoc(xaoObject);
137     xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1); // format = 1 for node indentation
138     xmlFreeDoc(doc);
139
140     return true;
141 }
142
143 const std::string XaoExporter::saveToXml(Xao* xaoObject)
144 throw (XAO_Exception)
145 {
146     xmlDocPtr doc = exportXMLDoc(xaoObject);
147
148     xmlChar *xmlbuff;
149     int buffersize;
150     xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1); // format = 1 for node indentation
151     xmlFreeDoc(doc);
152     xmlCleanupGlobals();
153
154     return (char*)xmlbuff;
155 }
156
157 xmlDocPtr XaoExporter::exportXMLDoc(Xao* xaoObject)
158 {
159     // Creating the Xml document
160     xmlDocPtr masterDocument = xmlNewDoc(BAD_CAST "1.0");
161     xmlNodePtr xao = xmlNewNode(0, C_TAG_XAO);
162     xmlDocSetRootElement(masterDocument, xao);
163
164     xmlNewProp(xao, C_ATTR_XAO_VERSION, BAD_CAST xaoObject->getVersion().c_str());
165     xmlNewProp(xao, C_ATTR_XAO_AUTHOR, BAD_CAST xaoObject->getAuthor().c_str());
166
167     if (xaoObject->getGeometry() != NULL)
168     {
169         exportGeometry(xaoObject->getGeometry(), masterDocument, xao);
170     }
171
172     exportGroups(xaoObject, xao);
173     exportFields(xaoObject, xao);
174
175     return masterDocument;
176 }
177
178 void XaoExporter::exportGeometricElements(Geometry* xaoGeometry,
179         xmlNodePtr topology, XAO::Dimension dim, const xmlChar* colTag, const xmlChar* eltTag)
180 {
181     xmlNodePtr vertices = xmlNewChild(topology, 0, colTag, 0);
182     xmlNewProp(vertices, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoGeometry->countElements(dim)).c_str());
183     GeometricElementList::iterator it = xaoGeometry->begin(dim);
184     for (; it != xaoGeometry->end(dim); it++)
185     {
186         int index = it->first;
187         GeometricElement elt = it->second;
188         xmlNodePtr vertex = xmlNewChild(vertices, 0, eltTag, 0);
189         xmlNewProp(vertex, C_ATTR_ELT_INDEX, BAD_CAST XaoUtils::intToString(index).c_str());
190         xmlNewProp(vertex, C_ATTR_ELT_NAME, BAD_CAST elt.getName().c_str());
191         xmlNewProp(vertex, C_ATTR_ELT_REFERENCE, BAD_CAST elt.getReference().c_str());
192     }
193 }
194
195 void XaoExporter::exportGeometry(Geometry* xaoGeometry, xmlDocPtr doc, xmlNodePtr xao)
196 {
197     // Geometric part
198     xmlNodePtr geometry = xmlNewChild(xao, 0, C_TAG_GEOMETRY, 0);
199     xmlNewProp(geometry, C_ATTR_GEOMETRY_NAME, BAD_CAST xaoGeometry->getName().c_str());
200
201     xmlNodePtr shape = xmlNewChild(geometry, 0, C_TAG_SHAPE, 0);
202     xmlNewProp(shape, C_ATTR_SHAPE_FORMAT, BAD_CAST XaoUtils::shapeFormatToString(xaoGeometry->getFormat()).c_str());
203     std::string txtShape = xaoGeometry->getShapeString();
204     xmlNodePtr cdata = xmlNewCDataBlock(doc, BAD_CAST txtShape.c_str(), txtShape.size());
205     xmlAddChild(shape, cdata);
206
207     xmlNodePtr topology = xmlNewChild(geometry, 0, C_TAG_TOPOLOGY, 0);
208
209     exportGeometricElements(xaoGeometry, topology, XAO::VERTEX, C_TAG_VERTICES, C_TAG_VERTEX);
210     exportGeometricElements(xaoGeometry, topology, XAO::EDGE, C_TAG_EDGES, C_TAG_EDGE);
211     exportGeometricElements(xaoGeometry, topology, XAO::FACE, C_TAG_FACES, C_TAG_FACE);
212     exportGeometricElements(xaoGeometry, topology, XAO::SOLID, C_TAG_SOLIDS, C_TAG_SOLID);
213 }
214
215 void XaoExporter::exportGroups(Xao* xaoObject, xmlNodePtr xao)
216 {
217     xmlNodePtr groups = xmlNewChild(xao, 0, C_TAG_GROUPS, 0);
218     xmlNewProp(groups, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoObject->countGroups()).c_str());
219
220     for (int i = 0; i < xaoObject->countGroups(); i++)
221     {
222         //Group* grp = (*it);
223         Group* grp = xaoObject->getGroup(i);
224         xmlNodePtr group = xmlNewChild(groups, 0, C_TAG_GROUP, 0);
225         xmlNewProp(group, C_ATTR_GROUP_NAME, BAD_CAST grp->getName().c_str());
226         xmlNewProp(group, C_ATTR_GROUP_DIM, BAD_CAST XaoUtils::dimensionToString(grp->getDimension()).c_str());
227         xmlNewProp(group, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(grp->count()).c_str());
228
229         for (std::set<int>::iterator it = grp->begin(); it != grp->end(); ++it)
230         {
231             int grpElt = (*it);
232             xmlNodePtr elt = xmlNewChild(group, 0, C_TAG_ELEMENT, 0);
233             xmlNewProp(elt, C_ATTR_ELEMENT_INDEX, BAD_CAST XaoUtils::intToString(grpElt).c_str());
234         }
235     }
236 }
237
238 void XaoExporter::exportFields(Xao* xaoObject, xmlNodePtr xao)
239 {
240     xmlNodePtr fields = xmlNewChild(xao, 0, C_TAG_FIELDS, 0);
241     xmlNewProp(fields, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(xaoObject->countFields()).c_str());
242
243     for (int i = 0; i < xaoObject->countFields(); i++)
244     {
245         Field* field = xaoObject->getField(i);
246         xmlNodePtr nodeField = xmlNewChild(fields, 0, C_TAG_FIELD, 0);
247         xmlNewProp(nodeField, C_ATTR_FIELD_NAME, BAD_CAST field->getName().c_str());
248         xmlNewProp(nodeField, C_ATTR_FIELD_TYPE, BAD_CAST XaoUtils::fieldTypeToString(field->getType()).c_str());
249         xmlNewProp(nodeField, C_ATTR_FIELD_DIMENSION, BAD_CAST XaoUtils::dimensionToString(field->getDimension()).c_str());
250
251         int nbComponents = field->countComponents();
252         xmlNodePtr components = xmlNewChild(nodeField, 0, C_TAG_COMPONENTS, 0);
253         xmlNewProp(components, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(nbComponents).c_str());
254
255         for (int j = 0; j < nbComponents; j++)
256         {
257             xmlNodePtr nodeComponent = xmlNewChild(components, 0, C_TAG_COMPONENT, 0);
258             xmlNewProp(nodeComponent, C_ATTR_COMPONENT_COLUMN, BAD_CAST XaoUtils::intToString(j).c_str());
259             xmlNewProp(nodeComponent, C_ATTR_COMPONENT_NAME, BAD_CAST field->getComponentName(j).c_str());
260         }
261
262         int nbSteps = field->countSteps();
263         xmlNodePtr nodeSteps = xmlNewChild(nodeField, 0, C_TAG_STEPS, 0);
264         xmlNewProp(nodeSteps, C_ATTR_COUNT, BAD_CAST XaoUtils::intToString(nbSteps).c_str());
265         for (stepIterator itStep = field->begin(); itStep != field->end(); itStep++)
266         {
267             Step* step = *itStep;
268             exportStep(step, field, nodeSteps);
269         }
270     }
271 }
272
273 void XaoExporter::exportStep(Step* step, Field* field, xmlNodePtr nodeSteps)
274 {
275     xmlNodePtr nodeStep = xmlNewChild(nodeSteps, 0, C_TAG_STEP, 0);
276     xmlNewProp(nodeStep, C_ATTR_STEP_NUMBER, BAD_CAST XaoUtils::intToString(step->getStep()).c_str());
277     if (step->getStamp() >= 0)
278     {
279         xmlNewProp(nodeStep, C_ATTR_STEP_STAMP, BAD_CAST XaoUtils::intToString(step->getStamp()).c_str());
280     }
281
282     for(int i = 0; i < step->countElements(); ++i)
283     {
284         xmlNodePtr nodeElt = xmlNewChild(nodeStep, 0, C_TAG_ELEMENT, 0);
285         xmlNewProp(nodeElt, C_ATTR_ELEMENT_INDEX, BAD_CAST XaoUtils::intToString(i).c_str());
286
287         for (int j = 0; j < step->countComponents(); ++j)
288         {
289             std::string content = step->getStringValue(i, j);
290             xmlNodePtr nodeValue = xmlNewChild(nodeElt, NULL, C_TAG_VALUE, BAD_CAST content.c_str());
291             xmlNewProp(nodeValue, C_ATTR_VALUE_COMPONENT, BAD_CAST XaoUtils::intToString(j).c_str());
292         }
293     }
294 }
295
296 const bool XaoExporter::readFromFile(const std::string& fileName, Xao* xaoObject)
297 throw (XAO_Exception)
298 {
299     // parse the file and get the DOM
300     int options = XML_PARSE_HUGE || XML_PARSE_NOCDATA;
301     xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, options);
302     if (doc == NULL)
303     {
304         throw XAO_Exception("Cannot read XAO file");
305     }
306
307     parseXMLDoc(doc, xaoObject);
308     return true;
309 }
310
311 const bool XaoExporter::setXML(const std::string& xml, Xao* xaoObject)
312 throw (XAO_Exception)
313 {
314     int options = XML_PARSE_HUGE || XML_PARSE_NOCDATA;
315     xmlDocPtr doc = xmlReadDoc(BAD_CAST xml.c_str(), "", NULL, options);
316     if (doc == NULL)
317     {
318         throw XAO_Exception("Cannot read XAO stream");
319     }
320
321     parseXMLDoc(doc, xaoObject);
322     return true;
323 }
324
325 void XaoExporter::parseXMLDoc(xmlDocPtr doc, Xao* xaoObject)
326 {
327     // Get the root element node
328     xmlNodePtr root = xmlDocGetRootElement(doc);
329     if (xmlStrcmp(root->name , C_TAG_XAO) != 0)
330         throw XAO_Exception("Cannot read XAO file: invalid format XAO node not found");
331
332     parseXaoNode(doc, root, xaoObject);
333
334     xmlFreeDoc(doc);       // free document
335     xmlCleanupParser();    // free globals
336 }
337
338 void XaoExporter::parseXaoNode(xmlDocPtr doc, xmlNodePtr xaoNode, Xao* xaoObject)
339 {
340     std::string version = readStringProp(xaoNode, C_ATTR_XAO_VERSION, false, "");
341     if (version != "")
342         xaoObject->setAuthor(version);
343
344     std::string author = readStringProp(xaoNode, C_ATTR_XAO_AUTHOR, false, "");
345     xaoObject->setAuthor(author);
346
347     for (xmlNodePtr node = xaoNode->children; node; node = node->next)
348     {
349         if (xmlStrcmp(node->name, C_TAG_GEOMETRY) == 0)
350             parseGeometryNode(doc, node, xaoObject);
351         else if (xmlStrcmp(node->name, C_TAG_GROUPS) == 0)
352             parseGroupsNode(node, xaoObject);
353         else if (xmlStrcmp(node->name, C_TAG_FIELDS) == 0)
354             parseFieldsNode(node, xaoObject);
355     }
356 }
357
358 void XaoExporter::parseGeometryNode(xmlDocPtr doc, xmlNodePtr geometryNode, Xao* xaoObject)
359 {
360     // get the shape and topo nodes
361     xmlNodePtr shapeNode = NULL;
362     xmlNodePtr topoNode = NULL;
363     for (xmlNodePtr node = geometryNode->children; node; node = node->next)
364     {
365         if (xmlStrcmp(node->name, C_TAG_SHAPE) == 0)
366             shapeNode = node;
367         else if (xmlStrcmp(node->name, C_TAG_TOPOLOGY) == 0)
368             topoNode = node;
369     }
370
371     std::string name = readStringProp(geometryNode, C_ATTR_GEOMETRY_NAME, false, "");
372     std::string strFormat = readStringProp(shapeNode, C_ATTR_SHAPE_FORMAT, true, "");
373     XAO::Format shapeFormat = XaoUtils::stringToShapeFormat(strFormat);
374     Geometry* geometry = Geometry::createGeometry(shapeFormat, name);
375
376     parseShapeNode(doc, shapeNode, geometry);
377     parseTopologyNode(topoNode, geometry);
378
379     xaoObject->setGeometry(geometry);
380 }
381
382 void XaoExporter::parseShapeNode(xmlDocPtr doc, xmlNodePtr shapeNode, Geometry* geometry)
383 {
384     if (geometry->getFormat() == XAO::BREP)
385     {
386         xmlChar* data = xmlNodeGetContent(shapeNode->children);
387         if (data == NULL)
388             throw XAO_Exception("Missing BREP");
389         geometry->setShapeString((char*)data);
390         xmlFree(data);
391     }
392     else
393     {
394         throw XAO_Exception(MsgBuilder() << "Shape format not supported: "
395                                          << XaoUtils::shapeFormatToString(geometry->getFormat()));
396     }
397 }
398
399 void XaoExporter::parseTopologyNode(xmlNodePtr topologyNode, Geometry* geometry)
400 {
401     for (xmlNodePtr node = topologyNode->children; node; node = node->next)
402     {
403         if (xmlStrcmp(node->name, C_TAG_VERTICES) == 0)
404             parseVerticesNode(node, geometry);
405         else if (xmlStrcmp(node->name, C_TAG_EDGES) == 0)
406             parseEdgesNode(node, geometry);
407         else if (xmlStrcmp(node->name, C_TAG_FACES) == 0)
408             parseFacesNode(node, geometry);
409         else if (xmlStrcmp(node->name, C_TAG_SOLIDS) == 0)
410             parseSolidsNode(node, geometry);
411     }
412 }
413
414 void XaoExporter::parseVerticesNode(xmlNodePtr verticesNode, Geometry* geometry)
415 {
416     int count = readIntegerProp(verticesNode, C_ATTR_COUNT, true, -1);
417     geometry->setCountVertices(count);
418
419     for (xmlNodePtr node = verticesNode->children; node; node = node->next)
420     {
421         if (xmlStrcmp(node->name, C_TAG_VERTEX) == 0)
422         {
423             int index = readIntegerProp(node, C_ATTR_ELT_INDEX, true, -1);
424             std::string name = readStringProp(node, C_ATTR_ELT_NAME, false, "");
425             std::string reference = readStringProp(node, C_ATTR_ELT_REFERENCE, true, "");
426
427             geometry->setVertex(index, name, reference);
428         }
429     }
430 }
431
432 void XaoExporter::parseEdgesNode(xmlNodePtr edgesNode, Geometry* geometry)
433 {
434     int count = readIntegerProp(edgesNode, C_ATTR_COUNT, true, -1);
435     geometry->setCountEdges(count);
436
437     for (xmlNodePtr node = edgesNode->children; node; node = node->next)
438     {
439         if (xmlStrcmp(node->name, C_TAG_EDGE) == 0)
440         {
441             int index = readIntegerProp(node, C_ATTR_ELT_INDEX, true, -1);
442             std::string name = readStringProp(node, C_ATTR_ELT_NAME, false, "");
443             std::string reference = readStringProp(node, C_ATTR_ELT_REFERENCE, true, "");
444
445             geometry->setEdge(index, name, reference);
446         }
447     }
448 }
449
450 void XaoExporter::parseFacesNode(xmlNodePtr facesNode, Geometry* geometry)
451 {
452     int count = readIntegerProp(facesNode, C_ATTR_COUNT, true, -1);
453     geometry->setCountFaces(count);
454
455     for (xmlNodePtr node = facesNode->children; node; node = node->next)
456     {
457         if (xmlStrcmp(node->name, C_TAG_FACE) == 0)
458         {
459             int index = readIntegerProp(node, C_ATTR_ELT_INDEX, true, -1);
460             std::string name = readStringProp(node, C_ATTR_ELT_NAME, false, "");
461             std::string reference = readStringProp(node, C_ATTR_ELT_REFERENCE, true, "");
462
463             geometry->setFace(index, name, reference);
464         }
465     }
466 }
467
468 void XaoExporter::parseSolidsNode(xmlNodePtr solidsNode, Geometry* geometry)
469 {
470     int count = readIntegerProp(solidsNode, C_ATTR_COUNT, true, -1);
471     geometry->setCountSolids(count);
472
473     for (xmlNodePtr node = solidsNode->children; node; node = node->next)
474     {
475         if (xmlStrcmp(node->name, C_TAG_SOLID) == 0)
476         {
477             int index = readIntegerProp(node, C_ATTR_ELT_INDEX, true, -1);
478             std::string name = readStringProp(node, C_ATTR_ELT_NAME, false, "");
479             std::string reference = readStringProp(node, C_ATTR_ELT_REFERENCE, true, "");
480
481             geometry->setSolid(index, name, reference);
482         }
483     }
484 }
485
486 void XaoExporter::parseGroupsNode(xmlNodePtr groupsNode, Xao* xaoObject)
487 {
488     for (xmlNodePtr node = groupsNode->children; node; node = node->next)
489     {
490         if (xmlStrcmp(node->name, C_TAG_GROUP) == 0)
491         {
492             parseGroupNode(node, xaoObject);
493         }
494     }
495 }
496
497 void XaoExporter::parseGroupNode(xmlNodePtr groupNode, Xao* xaoObject)
498 {
499     std::string strDimension = readStringProp(groupNode, C_ATTR_GROUP_DIM, true, "");
500     XAO::Dimension dim = XaoUtils::stringToDimension(strDimension);
501     Group* group = xaoObject->addGroup(dim);
502
503     std::string name = readStringProp(groupNode, C_ATTR_GROUP_NAME, false, "");
504     group->setName(name);
505
506     for (xmlNodePtr node = groupNode->children; node; node = node->next)
507     {
508         if (xmlStrcmp(node->name, C_TAG_ELEMENT) == 0)
509         {
510             int index = readIntegerProp(node, C_ATTR_ELEMENT_INDEX, true, -1);
511             group->add(index);
512         }
513     }
514 }
515
516 void XaoExporter::parseFieldsNode(xmlNodePtr fieldsNode, Xao* xaoObject)
517 {
518     for (xmlNodePtr node = fieldsNode->children; node; node = node->next)
519     {
520         if (xmlStrcmp(node->name, C_TAG_FIELD) == 0)
521         {
522             parseFieldNode(node, xaoObject);
523         }
524     }
525 }
526
527 void XaoExporter::parseFieldNode(xmlNodePtr fieldNode, Xao* xaoObject)
528 {
529     std::string strDimension = readStringProp(fieldNode, C_ATTR_FIELD_DIMENSION, true, "");
530     XAO::Dimension dim = XaoUtils::stringToDimension(strDimension);
531
532     std::string strType = readStringProp(fieldNode, C_ATTR_FIELD_TYPE, true, "");
533     XAO::Type type = XaoUtils::stringToFieldType(strType);
534
535     // we need to get the number of components first to create the field
536     xmlNodePtr componentsNode = NULL;
537     xmlNodePtr stepsNode = NULL;
538
539     for (xmlNodePtr node = fieldNode->children; node; node = node->next)
540     {
541         if (xmlStrcmp(node->name, C_TAG_COMPONENTS) == 0)
542             componentsNode = node;
543         else if (xmlStrcmp(node->name, C_TAG_STEPS) == 0)
544             stepsNode = node;
545     }
546
547     // ensure that the components node is defined
548     if (componentsNode == NULL)
549     {
550         throw XAO_Exception(MsgBuilder() << "Line " << fieldNode->line << ": "
551                                          << "No components defined for field.");
552     }
553
554     // create the field
555     int nbComponents = readIntegerProp(componentsNode, C_ATTR_COUNT, true, -1);
556     Field* field = xaoObject->addField(type, dim, nbComponents);
557
558     // parse the components
559     for (xmlNodePtr compNode = componentsNode->children; compNode; compNode = compNode->next)
560     {
561         std::string compName= readStringProp(compNode, C_ATTR_COMPONENT_NAME, false, "");
562         if (compName.size() > 0)
563         {
564             int col = readIntegerProp(compNode, C_ATTR_COMPONENT_COLUMN, true, -1);
565             field->setComponentName(col, compName);
566         }
567     }
568
569     // set the name
570     std::string name = readStringProp(fieldNode, C_ATTR_FIELD_NAME, false, "");
571     if (name.size() > 0) field->setName(name);
572
573     // read the steps
574     if (stepsNode != 0)
575     {
576         for (xmlNodePtr stepNode = stepsNode->children; stepNode; stepNode = stepNode->next)
577         {
578             if (xmlStrcmp(stepNode->name, C_TAG_STEP) == 0)
579             {
580                 parseStepNode(stepNode, field);
581             }
582         }
583     }
584 }
585
586 void XaoExporter::parseStepNode(xmlNodePtr stepNode, Field* field)
587 {
588     int stepNumber = readIntegerProp(stepNode, C_ATTR_STEP_NUMBER, true, -1);
589     Step* step = field->addNewStep(stepNumber);
590
591     int stepStamp = readIntegerProp(stepNode, C_ATTR_STEP_STAMP, false, -1);
592     if (stepStamp != -1)
593     {
594         step->setStamp(stepStamp);
595     }
596
597     for (xmlNodePtr eltNode = stepNode->children; eltNode; eltNode = eltNode->next)
598     {
599         if (xmlStrcmp(eltNode->name, C_TAG_ELEMENT) == 0)
600         {
601             parseStepElementNode(eltNode, step);
602         }
603     }
604 }
605
606 void XaoExporter::parseStepElementNode(xmlNodePtr eltNode, Step* step)
607 {
608     int index = readIntegerProp(eltNode, C_ATTR_ELT_INDEX, true, -1);
609
610     for (xmlNodePtr valNode = eltNode->children; valNode; valNode = valNode->next)
611     {
612         if (xmlStrcmp(valNode->name, C_TAG_VALUE) == 0)
613         {
614             int component = readIntegerProp(valNode, C_ATTR_VALUE_COMPONENT, true, -1);
615             xmlChar* data = xmlNodeGetContent(valNode->children);
616
617             if (data == NULL)
618             {
619                 throw XAO_Exception(MsgBuilder() << "Line " << valNode->line << ": no content for value.");
620             }
621
622             std::string value = (char*)data;
623             step->setStringValue(index, component, value);
624         }
625     }
626 }