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