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