00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00063 #ifndef _XMLFILEREADER_H
00064 #define _XMLFILEREADER_H
00065
00066 #include <gvectors-config.h>
00067
00068 #ifdef HAVE_LIBXML
00069 #include <stdlib.h>
00070
00071 #include <string>
00072
00073 #include <libxml++/libxml++.h>
00074 #include <gvectortypes.h>
00075 #include <gvexceptions.h>
00076 #include <vectorstore.h>
00077 #include <filereader.h>
00078 #include <visualvector.h>
00079 #include <color.h>
00080
00081 namespace GVectors {
00082
00083 #if HAVE_LIBXML == 2
00084
00089 const Glib::ustring VERSION_0_1 = "0.1";
00095 const Glib::ustring NODE_NAME_VECTOR = "vector";
00101 const Glib::ustring NODE_NAME_COORDINATES = "coordinates";
00108 const Glib::ustring NODE_NAME_COMPONENTS[4] = {
00109 "xcomp",
00110 "ycomp",
00111 "zcomp",
00112 ""
00113 };
00119 const Glib::ustring NODE_NAME_XCOMP = "xcomp";
00125 const Glib::ustring NODE_NAME_YCOMP = "ycomp";
00131 const Glib::ustring NODE_NAME_ZCOMP = "zcomp";
00137 const Glib::ustring NODE_NAME_COLOR = "color";
00144 const Glib::ustring NODE_NAME_COLORS[4] = {
00145 "red",
00146 "green",
00147 "blue",
00148 ""
00149 };
00155 const Glib::ustring NODE_NAME_RED = "red";
00161 const Glib::ustring NODE_NAME_GREEN = "green";
00167 const Glib::ustring NODE_NAME_BLUE = "blue";
00168 #else
00169
00174 const std::string VERSION_0_1 = "0.1";
00180 const std::string NODE_NAME_VECTOR = "vector";
00186 const std::string NODE_NAME_COORDINATES = "coordinates";
00193 const std::string NODE_NAME_COMPONENTS[4] = {
00194 "xcomp",
00195 "ycomp",
00196 "zcomp",
00197 ""
00198 };
00204 const std::string NODE_NAME_XCOMP = "xcomp";
00210 const std::string NODE_NAME_YCOMP = "ycomp";
00216 const std::string NODE_NAME_ZCOMP = "zcomp";
00222 const std::string NODE_NAME_COLOR = "color";
00229 const std::string NODE_NAME_COLORS[4] = {
00230 "red",
00231 "green",
00232 "blue",
00233 ""
00234 };
00240 const std::string NODE_NAME_RED = "red";
00246 const std::string NODE_NAME_GREEN = "green";
00252 const std::string NODE_NAME_BLUE = "blue";
00253 #endif
00254
00263 template<class Fct> class XMLReader : public FileReader<Fct> {
00264 private:
00270 std::string filename;
00280 xmlpp::DomParser parser;
00281
00292 GVector get_vector(const xmlpp::Node* coordnode) {
00293 if (coordnode==0)
00294 throw GVEXMLInvalid();
00295 #if HAVE_LIBXML == 2
00296 Glib::ustring nodename = coordnode->get_name();
00297 #else
00298 std::string nodename = coordnode->get_name();
00299 #endif
00300 if (nodename!=NODE_NAME_COORDINATES)
00301 throw GVEXMLInvalid();
00302
00303
00304 double dcomps[3];
00305 double* d_ptr = dcomps;
00306
00307 #if HAVE_LIBXML == 2
00308 const Glib::ustring* us_ptr = NODE_NAME_COMPONENTS;
00309 while(*us_ptr != Glib::ustring("") ) {
00310 #else
00311 const std::string* us_ptr = NODE_NAME_COMPONENTS;
00312 while(*us_ptr != std::string("") ) {
00313 #endif
00314 const xmlpp::Node* comp = *(coordnode->get_children(*us_ptr).begin());
00315 if (comp==0)
00316 throw GVEXMLInvalid();
00317 const xmlpp::ContentNode* ncontent = dynamic_cast<const xmlpp::ContentNode*>(*(comp->get_children().begin()));
00318 if (ncontent==0)
00319 throw GVEXMLInvalid();
00320 double dval = strtod(ncontent->get_content().c_str(), NULL);
00321 *d_ptr = dval;
00322 d_ptr++;
00323 us_ptr++;
00324 }
00325 return GVector(dcomps[0],dcomps[1],dcomps[2]);
00326 }
00327
00338 Color get_color(const xmlpp::Node* colnode) {
00339 if (colnode==0)
00340 throw GVEXMLInvalid();
00341
00342 #if HAVE_LIBXML == 2
00343 Glib::ustring nodename = colnode->get_name();
00344 #else
00345 std::string nodename = colnode->get_name();
00346 #endif
00347 if (nodename!=NODE_NAME_COLOR)
00348 throw GVEXMLInvalid();
00349
00350
00351 double dcols[3];
00352 double* d_ptr = dcols;
00353 #if HAVE_LIBXML == 2
00354 const Glib::ustring* us_ptr = NODE_NAME_COLORS;
00355 while(*us_ptr != Glib::ustring("") ) {
00356 #else
00357 const std::string* us_ptr = NODE_NAME_COLORS;
00358 while(*us_ptr != std::string("") ) {
00359 #endif
00360 const xmlpp::Node* col = *(colnode->get_children(*us_ptr).begin());
00361 if (col==0)
00362 throw GVEXMLInvalid();
00363 const xmlpp::ContentNode* ncontent = dynamic_cast<const xmlpp::ContentNode*>(*(col->get_children().begin()) );
00364 if (ncontent==0)
00365 throw GVEXMLInvalid();
00366 double dval = strtod(ncontent->get_content().c_str(), NULL);
00367 *d_ptr = dval;
00368 d_ptr++;
00369 us_ptr++;
00370 }
00371 return Color(dcols[0],dcols[1],dcols[2]);
00372 }
00373
00385 VisualVector get_visualvector(const xmlpp::Node* vvecnode) {
00386 if (vvecnode==0)
00387 throw GVEXMLInvalid();
00388
00389 #if HAVE_LIBXML == 2
00390 Glib::ustring nodename = vvecnode->get_name();
00391 #else
00392 std::string nodename = vvecnode->get_name();
00393 #endif
00394 if (nodename!=NODE_NAME_VECTOR)
00395 throw GVEXMLInvalid();
00396
00397 const xmlpp::Element* nodeelement = dynamic_cast<const xmlpp::Element*>(vvecnode);
00398 if (nodeelement==0)
00399 throw GVEXMLInvalid();
00400
00401
00402 const xmlpp::Attribute* attribute = nodeelement->get_attribute("tag");
00403 if (attribute==0)
00404 throw GVEXMLInvalid();
00405
00406
00407 const xmlpp::Node* cnode = *(vvecnode->get_children(NODE_NAME_COORDINATES).begin());
00408 GVector vec(get_vector(cnode));
00409
00410
00411 cnode = *(vvecnode->get_children(NODE_NAME_COLOR).begin());
00412 Color col(get_color(cnode));
00413 VisualVector return_value(vec);
00414 return_value.set_tag(attribute->get_value().c_str());
00415 return_value.set_color(col);
00416
00417 return return_value;
00418 }
00419
00434 void read_vectors(vslevel_t level, xmlpp::Node* node) {
00435 VisualVector vv(get_visualvector(node));
00436 FileReader<Fct>::put(level, vv);
00437
00438 xmlpp::Node::NodeList children = node->get_children(NODE_NAME_VECTOR);
00439 xmlpp::Node::NodeList::const_iterator it = children.begin();
00440 while (it!=children.end() ) {
00441 read_vectors(level+1, *it);
00442 it++;
00443 }
00444 }
00445
00446 public:
00459 XMLReader(std::string fn, VectorStore& vs, Fct callback) : FileReader<Fct>(vs, callback), filename(fn), parser(fn, true) {
00460 if (!parser)
00461 throw GVEXMLInvalid();
00462 }
00463
00472 XMLReader(const XMLReader& xr) : FileReader<Fct>(xr), filename(xr.filename), parser(filename, true) {
00473
00474 }
00475
00481 virtual ~XMLReader() {
00482
00483 }
00484
00494 void read() {
00495 const xmlpp::Node* parent_node = parser.get_document()->get_root_node();
00496 const xmlpp::Element* pn_element = dynamic_cast<const xmlpp::Element*>(parent_node);
00497 if (pn_element==0)
00498 throw GVEXMLInvalid();
00499
00500 const xmlpp::Attribute* version = pn_element->get_attribute("version");
00501 if (version->get_value()!=VERSION_0_1)
00502 throw GVEXMLInvalid();
00503
00504 const xmlpp::Node::NodeList vectors = parent_node->get_children(NODE_NAME_VECTOR);
00505 xmlpp::Node::NodeList::const_iterator it = vectors.begin();
00506 while (it!=vectors.end() ) {
00507 read_vectors(TOP_LEVEL_NUM, *it);
00508 it++;
00509 }
00510 }
00511 };
00512 }
00513
00514 #endif
00515
00516 #endif