00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef VCSN_XML_BUILDERS_HXX
00018 # define VCSN_XML_BUILDERS_HXX
00019
00020 # include <sstream>
00021
00022 # include <vaucanson/algebra/concept/letter.hh>
00023 # include <vaucanson/algebra/implementation/series/rat/exp.hh>
00024 # include <vaucanson/design_pattern/element.hh>
00025 # include <vaucanson/xml/xml_exp_visitor.hh>
00026 # include <vaucanson/algebra/concept/monoid_base.hh>
00027 # include <vaucanson/algebra/implementation/monoid/monoid_rep.hh>
00028
00029 namespace vcsn
00030 {
00031 namespace xml
00032 {
00036 template <typename T>
00037 monGenAction<T>::monGenAction(const T&)
00038 {
00039 static_error(need_to_specialize_monGenAction_for_T)
00040 }
00041
00042 template <typename T>
00043 monGenAction<vcsn::algebra::FreeMonoid<T> >::
00044 monGenAction(monoid_t& monoid)
00045 : alphabet_(monoid.alphabet())
00046 {
00047 }
00048
00049 template <typename T, typename U, typename V>
00050 monGenAction<vcsn::Element<vcsn::algebra::Series<T, U>, V> >::
00051 monGenAction(series_t& s)
00052 : s_(s)
00053 {
00054 }
00055
00056
00057 template <typename T>
00058 void
00059 monGenAction<vcsn::algebra::FreeMonoid<T> >::
00060 operator () (const std::string& str)
00061 {
00062 alphabet_.insert(str);
00063 }
00064
00065
00066 template <typename T, typename U, typename V>
00067 void
00068 monGenAction<vcsn::Element<vcsn::algebra::Series<T, U>, V> >::
00069 operator () (const std::string& str)
00070 {
00071 std::pair<bool, letter_t> res =
00072 parse_letter(s_.structure().monoid().alphabet(), str);
00073
00074 if (res.first)
00075 {
00076 typename series_t::monoid_elt_t m(s_.structure().monoid(),
00077 res.second);
00078 series_t tmp(s_.structure(), m);
00079 s_ = s_ * tmp;
00080 }
00081 else
00082 error::notletter(str);
00083 }
00084
00088 template <typename T, typename U>
00089 monGenHandler<T, U>::monGenHandler (xercesc::SAX2XMLReader* parser,
00090 Handler& root,
00091 const monGenAction<U>& action,
00092 const XMLCh* value)
00093 : Handler(parser, root),
00094 value_(value),
00095 action_(action)
00096 {
00097 }
00098
00099 template <typename T, typename U>
00100 void
00101 monGenHandler<T, U>::start (const XMLCh* const,
00102 const XMLCh* const localname,
00103 const XMLCh* const,
00104 const xercesc::Attributes&)
00105 {
00106 error::token(localname);
00107 }
00108
00109 template <typename T, typename U>
00110 void
00111 monGenHandler<T, U>::end (const XMLCh* const,
00112 const XMLCh* const localname,
00113 const XMLCh* const)
00114 {
00115 if (xercesc::XMLString::equals(eq_.monGen, localname))
00116 {
00117 if (value_)
00118 {
00119 std::string letter = xmlstr(value_);
00120 action_(letter);
00121 parser_->setContentHandler(&root_);
00122 }
00123 else
00124 {
00125 error::missattrs(localname, "value");
00126 }
00127 }
00128 else
00129 error::token(localname);
00130 }
00131
00135 template <typename T, typename U>
00136 monGenTupleHandler<T, U>::monGenTupleHandler (xercesc::SAX2XMLReader* parser,
00137 Handler& root,
00138 const monGenAction<U>& action)
00139 : Handler(parser, root),
00140 value_("("),
00141 wait_begin_(true),
00142 count_(0),
00143 action_(action)
00144 {
00145 }
00146
00147 template <typename T, typename U>
00148 void
00149 monGenTupleHandler<T, U>::start (const XMLCh* const,
00150 const XMLCh* const localname,
00151 const XMLCh* const,
00152 const xercesc::Attributes& attrs)
00153 {
00154 if (xercesc::XMLString::equals(eq_.monCompGen, localname) && wait_begin_)
00155 {
00156 wait_begin_ = false;
00157 const XMLCh* attr = tools::get_attribute(attrs, eq_.value);
00158 if (!attr)
00159 error::missattrs(localname, "value");
00160 value_ += xmlstr(attr);
00161 if (count_ == algebra::letter_traits<typename T::alphabet_t::letter_t>::dim() - 2)
00162 value_ += ",";
00163 }
00164 else
00165 error::token(localname);
00166 }
00167
00168 template <typename T, typename U>
00169 void
00170 monGenTupleHandler<T, U>::end (const XMLCh* const,
00171 const XMLCh* const localname,
00172 const XMLCh* const)
00173 {
00174 int dim = algebra::letter_traits<typename T::alphabet_t::letter_t>::
00175 dim();
00176
00177 if (xercesc::XMLString::equals(eq_.monGen, localname)
00178 && count_ == dim)
00179 {
00180 value_ += ")";
00181 action_(value_);
00182 parser_->setContentHandler(&root_);
00183 }
00184 else if (xercesc::XMLString::equals(eq_.monCompGen, localname)
00185 && !wait_begin_ && count_ < dim)
00186 {
00187 wait_begin_ = true;
00188 count_++;
00189 }
00190 else
00191 error::token(localname);
00192 }
00193
00197 template <typename T>
00198 FreeMonoidHandler<T>::FreeMonoidHandler (xercesc::SAX2XMLReader* parser,
00199 Handler& root,
00200 T& monoid)
00201 : Handler(parser, root),
00202 monoid_(monoid),
00203 user_rep_(false),
00204 mongenh_(0),
00205 unsuph_(parser, *this)
00206 {
00207 }
00208
00209 template <typename T>
00210 void
00211 FreeMonoidHandler<T>::start (const XMLCh* const,
00212 const XMLCh* const localname,
00213 const XMLCh* const,
00214 const xercesc::Attributes& attrs)
00215 {
00216 using namespace xercesc;
00217
00218 if (XMLString::equals(eq_.monGen, localname))
00219 {
00220
00221 monGenAction<T> action(monoid_);
00222
00223
00224 delete mongenh_;
00225
00226
00227 if (algebra::letter_traits<typename T::alphabet_t::letter_t>::kind() == "simple")
00228 {
00229 const XMLCh* value = tools::get_attribute(attrs, eq_.value);
00230 mongenh_ = new monGenHandler<T, T>(parser_, *this, action, value);
00231 }
00232 else
00233 mongenh_ = new monGenTupleHandler<T, T>(parser_, *this, action);
00234
00235
00236 parser_->setContentHandler(mongenh_);
00237 }
00238 else if (XMLString::equals(eq_.genSort, localname))
00239 {
00240
00241 parser_->setContentHandler(&unsuph_);
00242 }
00243 else if (XMLString::equals(eq_.writingData, localname))
00244 {
00245 algebra::MonoidRep<T> rep;
00246 if (tools::has_attribute(attrs, eq_.identitySymbol))
00247 rep.empty = xmlstr(tools::get_attribute(attrs, eq_.identitySymbol));
00248 if (tools::has_attribute(attrs, eq_.concat))
00249 rep.concat = xmlstr(tools::get_attribute(attrs, eq_.concat));
00250 monoid_.set_representation(rep);
00251 user_rep_ = true;
00252 parser_->setContentHandler(&unsuph_);
00253 }
00254 else
00255 error::token(localname);
00256 }
00257
00258 template <typename T>
00259 void
00260 FreeMonoidHandler<T>::end (const XMLCh* const,
00261 const XMLCh* const localname,
00262 const XMLCh* const)
00263 {
00264 using namespace xercesc;
00265
00266 if (XMLString::equals(eq_.monoid, localname))
00267 {
00268
00269 delete mongenh_;
00270
00271
00272 T new_monoid(monoid_.alphabet());
00273
00274
00275 if (user_rep_)
00276 new_monoid.set_representation(*(monoid_.representation()));
00277
00278 monoid_ = new_monoid;
00279
00280
00281 parser_->setContentHandler(&root_);
00282 }
00283 else if (!XMLString::equals(eq_.monGen, localname))
00284 error::token(localname);
00285 }
00286
00290 template <typename T>
00291 SeriesRepresentationHandler<T>::SeriesRepresentationHandler(xercesc::SAX2XMLReader* parser,
00292 Handler& root,
00293 T& srep)
00294 : Handler(parser, root),
00295 rep_(srep),
00296 unsuph_(parser, *this)
00297 {
00298 }
00299
00300 template <typename T>
00301 void
00302 SeriesRepresentationHandler<T>::start(const XMLCh* const,
00303 const XMLCh* const localname,
00304 const XMLCh* const,
00305 const xercesc::Attributes& attrs)
00306 {
00307 error::token(localname);
00308 }
00309
00310 template <typename T>
00311 void
00312 SeriesRepresentationHandler<T>::end(const XMLCh* const,
00313 const XMLCh* const localname,
00314 const XMLCh* const)
00315 {
00316 using namespace xercesc;
00317
00318 if (XMLString::equals(eq_.writingData, localname))
00319 {
00320
00321 parser_->setContentHandler(&root_);
00322 }
00323 else
00324 error::token(localname);
00325 }
00326
00327 namespace builders
00328 {
00329 template <typename T>
00330 typename T::monoid_t*
00331 create_monoid(T& param,
00332 const XMLCh* const localname,
00333 const xercesc::Attributes& attrs,
00334 XMLEq& eq)
00335 {
00336
00337 typename T::monoid_t::alphabet_t at;
00338 typedef typename T::monoid_t monoid_t;
00339
00340 monoid_t* monoid = new monoid_t(at);
00341 builders::check_monoid_consistency(param, localname, attrs, eq);
00342
00343 return monoid;
00344 }
00345
00346 template <typename T>
00347 Handler*
00348 create_monoidh (T& monoid,
00349 const xercesc::Attributes&,
00350 xercesc::SAX2XMLReader* parser,
00351 Handler& root)
00352 {
00353 return new vcsn::xml::FreeMonoidHandler<T>(parser, root, monoid);
00354 }
00355
00356 template <typename T>
00357 typename T::series_set_t::series_rep_t*
00358 create_series_representation(T& param,
00359 const XMLCh* const localname,
00360 const xercesc::Attributes& attrs,
00361 XMLEq& eq)
00362 {
00363
00364 typedef typename T::series_set_t::series_rep_t series_rep_t;
00365
00366 return new series_rep_t();
00367 }
00368
00369 template <typename T>
00370 Handler*
00371 create_series_representationh(T& srep,
00372 const xercesc::Attributes& attrs,
00373 xercesc::SAX2XMLReader* parser,
00374 Handler& root,
00375 XMLEq& eq)
00376 {
00377 if (tools::has_attribute(attrs, eq.openPar))
00378 srep.open_par = xmlstr(tools::get_attribute(attrs, eq.openPar));
00379 if (tools::has_attribute(attrs, eq.closePar))
00380 srep.close_par = xmlstr(tools::get_attribute(attrs, eq.closePar));
00381 if (tools::has_attribute(attrs, eq.plusSym))
00382 srep.plus = xmlstr(tools::get_attribute(attrs, eq.plusSym));
00383 if (tools::has_attribute(attrs, eq.timesSym))
00384 srep.times = xmlstr(tools::get_attribute(attrs, eq.timesSym));
00385 if (tools::has_attribute(attrs, eq.starSym))
00386 srep.star = xmlstr(tools::get_attribute(attrs, eq.starSym));
00387 if (tools::has_attribute(attrs, eq.zeroSym))
00388 srep.zero = xmlstr(tools::get_attribute(attrs, eq.zeroSym));
00389 if (tools::has_attribute(attrs, eq.openWeight))
00390 srep.open_weight = xmlstr(tools::get_attribute(attrs, eq.openWeight));
00391 if (tools::has_attribute(attrs, eq.closeWeight))
00392 srep.close_weight = xmlstr(tools::get_attribute(attrs, eq.closeWeight));
00393 if (tools::has_attribute(attrs, eq.spacesSym))
00394 {
00395 srep.spaces.clear();
00396 srep.spaces.push_back(xmlstr(tools::get_attribute(attrs, eq.spacesSym)));
00397 }
00398
00399 return new SeriesRepresentationHandler<T>(parser, root, srep);
00400 }
00401
00402 }
00403
00407 template <typename T>
00408 NumSemiringHandler<T>::NumSemiringHandler (xercesc::SAX2XMLReader* parser,
00409 Handler& root,
00410 T& semiring)
00411 : Handler(parser, root),
00412 semiring_(semiring),
00413 unsuph_(parser, *this)
00414 {
00415 }
00416
00417 template <typename T>
00418 void
00419 NumSemiringHandler<T>::start (const XMLCh* const,
00420 const XMLCh* const localname,
00421 const XMLCh* const,
00422 const xercesc::Attributes&)
00423 {
00424 if (xercesc::XMLString::equals(eq_.writingData, localname))
00425 parser_->setContentHandler(&unsuph_);
00426 else
00427 error::token(localname);
00428 }
00429
00430 template <typename T>
00431 void
00432 NumSemiringHandler<T>::end (const XMLCh* const,
00433 const XMLCh* const localname,
00434 const XMLCh* const)
00435 {
00436 if (xercesc::XMLString::equals(eq_.semiring, localname))
00437 parser_->setContentHandler(&root_);
00438 else
00439 error::token(localname);
00440 }
00441
00442 namespace builders
00443 {
00444 template <typename T>
00445 typename T::semiring_t*
00446 create_semiring (T&,
00447 const XMLCh* const localname,
00448 const xercesc::Attributes& attrs)
00449 {
00450 typedef typename T::semiring_t semiring_t;
00451 semiring_t* semiring = new semiring_t();
00452
00453 typedef typename T::semiring_elt_t semiring_elt_t;
00454 semiring_elt_t elt;
00455 builders::check_semiring_consistency(elt, localname, attrs);
00456
00457 return semiring;
00458 }
00459
00460 template <typename T>
00461 Handler*
00462 create_semiringh(T& semiring,
00463 const xercesc::Attributes&,
00464 xercesc::SAX2XMLReader* parser,
00465 Handler& root)
00466 {
00467 return new NumSemiringHandler<T>(parser, root, semiring);
00468 }
00469
00470 }
00471
00475 template <typename T>
00476 class MonElmtHandler;
00477
00478 template <typename T>
00479 class WeightHandler;
00480
00481 namespace builders
00482 {
00483
00484 template <typename S, typename T>
00485 RegexpHandler<S>*
00486 create_monElmth(xercesc::SAX2XMLReader* parser,
00487 RegexpHandler<T>& root,
00488 S param)
00489 {
00490 return new MonElmtHandler<S>(parser, root, param);
00491 }
00492
00493 template <typename T>
00494 RegexpHandler<T>*
00495 create_weighth(xercesc::SAX2XMLReader* parser,
00496 RegexpHandler<T>& root,
00497 T param,
00498 const xercesc::Attributes& attrs)
00499 {
00500 typename T::monoid_elt_value_t m =
00501 vcsn::algebra::identity_as<typename T::monoid_elt_value_t>::of(param.structure().monoid()).value();
00502 const std::string val(xmlstr(tools::get_attribute(attrs, root.eq().value)));
00503 std::string::const_iterator i = val.begin();
00504 typename T::semiring_elt_t w(param.structure().semiring());
00505 if (!parse_weight(w, val, i))
00506 error::attrs(tools::get_attribute(attrs, "localname"), "value", val);
00507 param.assoc(m, w.value());
00508 return new WeightHandler<T>(parser, root, param);
00509 }
00510 }
00511
00515 namespace builders
00516 {
00517
00518 template <class T>
00519 const char* get_semiring_set(const T&)
00520 { return "undefined"; }
00521
00522 # define GET_SEMIRING_SET(T, Value) \
00523 const char* get_semiring_set(const T&) \
00524 { return Value; }
00525
00526 GET_SEMIRING_SET(bool, "B")
00527 GET_SEMIRING_SET(double, "R")
00528 GET_SEMIRING_SET(float, "R")
00529 GET_SEMIRING_SET(int, "Z")
00530 # undef GET_SEMIRING_SET
00531
00532 template <class S>
00533 const char* get_semiring_operations(const S&)
00534 { return "classical"; }
00535
00536 template <typename T>
00537 void
00538 check_monoid_consistency(T&,
00539 const XMLCh* const localname,
00540 const xercesc::Attributes& attrs,
00541 XMLEq& eq)
00542 {
00543 const XMLCh* val = tools::get_attribute(attrs, eq.type);
00544 if (!xercesc::XMLString::equals(val, eq.free))
00545 error::attrs(localname, xmlstr(eq.type), xmlstr(val));
00546 };
00547
00548 template <typename T>
00549 void
00550 check_semiring_consistency (T& param,
00551 const XMLCh* const localname,
00552 const xercesc::Attributes& attrs)
00553 {
00554 std::string set(xmlstr(tools::get_attribute(attrs, "set")));
00555 if (builders::get_semiring_set(param.value()) != set)
00556 error::attrs(localname, "set", set);
00557 std::string op(xmlstr(tools::get_attribute(attrs, "operations")));
00558 if (builders::get_semiring_operations(param.structure()) != op)
00559 error::attrs(localname, "operations", op);
00560 };
00561
00562 template <class T>
00563 const char* get_monoid_gen_sort(const T&)
00564 { return "undefined"; }
00565 # define GET_MONOID_GEN_SORT(T, Value) \
00566 const char* get_monoid_gen_sort(const T&) \
00567 { return Value; }
00568
00569 GET_MONOID_GEN_SORT(char, "letters")
00570 GET_MONOID_GEN_SORT(int, "integers")
00571 # undef GET_MONOID_GEN_SORT
00572
00573 template <class T>
00574 const char* get_monoid_gen_sort(const T&, int)
00575 { return "undefined"; }
00576
00577 template <class U, class V>
00578 const char* get_monoid_gen_sort(const std::pair<U,V>& a, int i)
00579 {
00580 return i ? get_monoid_gen_sort(a.second) : get_monoid_gen_sort(a.first);
00581 }
00582 }
00583
00584 namespace builders
00585 {
00586 template <typename T>
00587 void
00588 create_semiring_node(const T& aut,
00589 xercesc::DOMDocument* doc,
00590 xercesc::DOMElement* root)
00591 {
00592 typedef typename T::semiring_elt_t semiring_elt_t;
00593 semiring_elt_t semiring(aut.series().semiring());
00594 xercesc::DOMElement* node = tools::create_element(doc, "semiring");
00595 tools::set_attribute(node, "type", "numerical");
00596 tools::set_attribute(node, "set", get_semiring_set(semiring.value()));
00597 tools::set_attribute(node, "operations", get_semiring_operations(semiring.structure()));
00598 root->appendChild(node);
00599 }
00600 template <typename T>
00601 void
00602 create_monoid_node(const T& aut,
00603 xercesc::DOMDocument* doc,
00604 xercesc::DOMElement* root)
00605 {
00606 std::string letter_kind = algebra::letter_traits<typename T::monoid_t::alphabet_t::letter_t>::kind();
00607 xercesc::DOMElement* node = tools::create_element(doc, "monoid");
00608 tools::set_attribute(node, "type", "free");
00609 tools::set_attribute(node, "genDescrip", "enum");
00610 tools::set_attribute(node, "genKind", letter_kind);
00611 root->appendChild(node);
00612
00613 xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
00614 tools::set_attribute(writingData, "identitySym", aut.series().monoid().representation()->empty);
00615 tools::set_attribute(writingData, "timesSym", aut.series().monoid().representation()->concat);
00616 node->appendChild(writingData);
00617
00618 typedef typename T::monoid_t::alphabet_t::const_iterator alphabet_iterator;
00619
00620 if (letter_kind == "simple")
00621 tools::set_attribute(node, "genSort", get_monoid_gen_sort(*(aut.series().monoid().alphabet().begin())));
00622 else
00623 {
00624 std::stringstream genDim;
00625 int dim = algebra::letter_traits<typename T::monoid_t::alphabet_t::letter_t>::dim();
00626 genDim << dim;
00627 tools::set_attribute(node, "genDim", genDim.str());
00628 xercesc::DOMElement* genSort = tools::create_element(doc, "genSort");
00629 node->appendChild(genSort);
00630 xercesc::DOMElement* genCompSort;
00631 for (int i = 0; i != dim; i++)
00632 {
00633 genCompSort = tools::create_element(doc, "genCompSort");
00634 tools::set_attribute(genCompSort, "value", get_monoid_gen_sort(*(aut.series().monoid().alphabet().begin()), i));
00635 genSort->appendChild(genCompSort);
00636 }
00637 }
00638
00639 create_monGen_node<typename T::monoid_t::alphabet_t::letter_t> monGen_maker;
00640 for_all_letters(l, aut.series().monoid().alphabet())
00641 monGen_maker(*l, doc, node);
00642
00643 }
00644
00645 template <typename T>
00646 void
00647 create_regexp_node(const T& e,
00648 xercesc::DOMDocument* doc,
00649 xercesc::DOMElement* root,
00650 const char* root_name)
00651 {
00652 typedef typename T::value_t::monoid_elt_value_t monoid_elt_value_t;
00653 typedef typename T::value_t::semiring_elt_value_t semiring_elt_value_t;
00654 typedef typename rat::exp<monoid_elt_value_t, semiring_elt_value_t> krat_exp_impl_t;
00655
00656 typedef Element<typename T::set_t, krat_exp_impl_t > krat_exp_t;
00657
00658 krat_exp_t res(e);
00659 rat::XmlExpVisitor<monoid_elt_value_t, semiring_elt_value_t> v(doc, root_name);
00660 res.value().accept(v);
00661 root->appendChild(v.get());
00662 }
00663
00664 template <typename U>
00665 void
00666 create_monElmt_node(const U& word,
00667 xercesc::DOMDocument* doc,
00668 xercesc::DOMElement* root)
00669 {
00670 xercesc::DOMElement* node;
00671
00672 if (word.empty())
00673 node = tools::create_element(doc, "one");
00674 else
00675 {
00676 node = tools::create_element(doc, "monElmt");
00677 create_monGen_node<typename U::value_type> monGen_maker;
00678 for (typename U::const_iterator i = word.begin(); i != word.end(); ++i)
00679 monGen_maker(*i, doc, node);
00680 }
00681 root->appendChild(node);
00682 }
00683
00684 template <typename T>
00685 void
00686 create_type_writingData_node(const T& aut,
00687 xercesc::DOMDocument* doc,
00688 xercesc::DOMElement* root)
00689 {
00690 xercesc::DOMElement* writingData = tools::create_element(doc, "writingData");
00691
00692
00693 tools::set_attribute(writingData, "plusSym", aut.series().representation()->plus);
00694 tools::set_attribute(writingData, "timesSym", aut.series().representation()->times);
00695 tools::set_attribute(writingData, "starSym", aut.series().representation()->star);
00696 tools::set_attribute(writingData, "zeroSym", aut.series().representation()->zero);
00697 tools::set_attribute(writingData, "weightOpening", aut.series().representation()->open_weight);
00698 tools::set_attribute(writingData, "weightClosing", aut.series().representation()->close_weight);
00699 tools::set_attribute(writingData, "openPar", aut.series().representation()->open_par);
00700 tools::set_attribute(writingData, "closePar", aut.series().representation()->close_par);
00701 tools::set_attribute(writingData, "spacesSym", aut.series().representation()->spaces.front());
00702
00703 root->appendChild(writingData);
00704 }
00705
00706
00707
00708 template <typename U>
00709 struct create_monGen_node
00710 {
00711 void
00712 operator()(const U& letter,
00713 xercesc::DOMDocument* doc,
00714 xercesc::DOMElement* root)
00715 {
00716 xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00717
00718 tools::set_attribute(gen, "value",
00719 algebra::letter_traits<U>::
00720 letter_to_literal(letter));
00721
00722 root->appendChild(gen);
00723 }
00724 };
00725
00726
00727
00728
00729 template <typename U, typename V>
00730 struct create_monGen_node<std::pair<U, V> >
00731 {
00732 void
00733 operator()(const std::pair<U, V>& letter,
00734 xercesc::DOMDocument* doc,
00735 xercesc::DOMElement* root)
00736 {
00737 xercesc::DOMElement* gen = tools::create_element(doc, "monGen");
00738
00739 std::stringstream sstr_first;
00740 std::stringstream sstr_second;
00741 xercesc::DOMElement* first = tools::create_element(doc, "monCompGen");
00742 xercesc::DOMElement* second = tools::create_element(doc, "monCompGen");
00743 sstr_first << letter.first;
00744 sstr_second << letter.second;
00745 tools::set_attribute(first, "value", sstr_first.str());
00746 tools::set_attribute(second, "value", sstr_second.str());
00747 gen->appendChild(first);
00748 gen->appendChild(second);
00749
00750 root->appendChild(gen);
00751 }
00752 };
00753
00754 }
00755
00756 }
00757
00758 }
00759
00760 #endif // ! VCSN_XML_BUILDERS_HXX