ximol/xml/context.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002  *                                                                           *
00003  * library XiMoL                                                             *
00004  * Copyright (C) 2002, 2003, 2004 Florent Tournois                           *
00005  *                                                                           *
00006  * This library is free software; you can redistribute it and/or             *
00007  * modify it under the terms of the GNU Lesser General Public                *
00008  * License as published by the Free Software Foundation; either              *
00009  * version 2.1 of the License, or (at your option) any later version.        *
00010  *                                                                           *
00011  * This library is distributed in the hope that it will be useful,           *
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU         *
00014  * Lesser General Public License for more details.                           *
00015  *                                                                           *
00016  * You should have received a copy of the GNU Lesser General Public          *
00017  * License along with this library; if not, write to the Free Software       *
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA   *
00019  *                                                                           *
00020 \*****************************************************************************/
00021 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00022 /** \file 
00023         \brief context (implementation).
00024 
00025         \author Tournois Florent
00026         \version 1.0
00027 
00028     $Id: context.cpp,v 1.12 2004/02/22 10:27:34 tournois Exp $
00029     $Log: context.cpp,v $
00030     Revision 1.12  2004/02/22 10:27:34  tournois
00031     Add some doc.
00032 
00033     Revision 1.11  2004/02/22 09:54:21  tournois
00034     Change years on the copyright.
00035 
00036     Revision 1.10  2004/01/19 20:40:55  tournois
00037     Add min, max and digits facet.
00038     Create the control flow file.
00039 
00040     Revision 1.9  2003/12/10 20:32:18  tournois
00041     Fix somes bugs about attributes and now tests are all check.
00042 
00043     Revision 1.8  2003/12/04 14:34:52  hfp
00044     XIMOL_XML_NAMESPACE_PATH::attributes changed
00045 
00046     Revision 1.7  2003/11/19 20:52:54  tournois
00047     Add new manipulator for stag and etag.
00048     Correct bugs and add tests.
00049 
00050     Revision 1.6  2003/11/18 18:54:52  tournois
00051     Add str_cast and drop the transformation.hpp file.
00052 
00053     Revision 1.5  2003/11/16 13:25:25  tournois
00054     Change the error to use wide string.
00055     Change the translation to use wide string.
00056 
00057     Revision 1.4  2003/11/15 22:52:57  tournois
00058     Add somes function arround attributes and tests for attributes.
00059 
00060     Revision 1.3  2003/11/02 19:23:01  tournois
00061     Go to the boost coding standard.
00062     Change all name to lower case.
00063 
00064     Revision 1.2  2003/10/25 13:53:40  hfp
00065     review and separation
00066 
00067     Revision 1.1  2003/09/24 08:28:18  tournois
00068     Create the namespace Encoders, Parser, Xml
00069     Change the library organization.
00070     add VC7.1 project for this organization.
00071 
00072   */
00073 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00074 #include <ximol/xml/context.hpp>
00075 #include <ximol/str_cast.hpp>
00076 #include <ximol/translation.hpp>
00077 #include <ximol/error.hpp>
00078 #include <ximol/macros.hpp>
00079 
00080 
00081 XIMOL_XML_BEGIN_NAMESPACE
00082 
00083 //-----------------------------------------------------------------------------
00084 // Clear the string
00085 //-----------------------------------------------------------------------------
00086 template <class T>
00087 void clear_string(T &xstr)
00088 {
00089         if (!xstr.empty()) xstr.erase(xstr.begin(),xstr.end()); 
00090 }
00091 
00092 //-----------------------------------------------------------------------------
00093 // 
00094 //-----------------------------------------------------------------------------
00095 context::context()
00096         : entities_()
00097         , parameter_entities_()
00098         , processing_instructions_()
00099         , notations_decl_()
00100         , version_num_(L"1.0")
00101         , standalone_decl_(false)
00102         , encoding_decl_(str< ::std::wstring>::cast(XIMOL_DEFAULT_ENCODING))
00103         , levels_()
00104 {
00105         add_entity(L"lt"  , L"&#60;");
00106         add_entity(L"gt"  , L">");
00107         add_entity(L"amp" , L"&#38;");
00108         add_entity(L"apos", L"'");
00109         add_entity(L"quot", L"\"");
00110 }
00111 
00112 //-----------------------------------------------------------------------------
00113 // 
00114 //-----------------------------------------------------------------------------
00115 bool context::add_entity(const xstring& entity_name, const xstring& entity_value, const xstring& system_literal, const xstring & pubid_literal, const xstring & ndata_name)
00116 {
00117         entity_def_type& entity=entities_[entity_name];
00118         clear_string(entity.entity_value);
00119         clear_string(entity.name_);
00120         clear_string(entity.pubid_literal_);
00121         clear_string(entity.system_literal_);
00122 
00123         if (entity_value.length()>0) 
00124         {
00125                 entity.entity_value=entity_value;
00126                 return true;
00127         }
00128         entity.pubid_literal_=pubid_literal;
00129         entity.system_literal_=system_literal;
00130         entity.name_=ndata_name;
00131         return true;
00132 }
00133 
00134 //-----------------------------------------------------------------------------
00135 // 
00136 //-----------------------------------------------------------------------------
00137 bool context::add_paramter_entity(const xstring& entity_name, const xstring& entity_value, const xstring& system_literal, const xstring & pubid_literal)
00138 {
00139         pe_def_type& entity=parameter_entities_[entity_name];
00140         clear_string(entity.entity_value);
00141         clear_string(entity.pubid_literal_);
00142         clear_string(entity.system_literal_);
00143 
00144         if (entity_value.length()>0) 
00145         {
00146                 entity.entity_value=entity_value;
00147                 return true;
00148         }
00149         entity.pubid_literal_=pubid_literal;
00150         entity.system_literal_=system_literal;
00151         return true;
00152 }
00153 
00154 //-----------------------------------------------------------------------------
00155 // 
00156 //-----------------------------------------------------------------------------
00157 bool context::add_notation_decl(const xstring& name, const xstring& system_literal, const xstring& pubid_literal)
00158 {
00159         notation_decl_type ndt;
00160         ndt.system_literal_=system_literal;
00161         ndt.pubid_literal_=pubid_literal;
00162         notations_decl_[name]=ndt;
00163         return true;
00164 }
00165 
00166 //-----------------------------------------------------------------------------
00167 // 
00168 //-----------------------------------------------------------------------------
00169 bool context::add_processing_instruction(const xstring& pi_target, const xstring& value)
00170 {
00171         processing_instructions_[pi_target]=value;
00172         return true;
00173 }
00174 
00175 //-----------------------------------------------------------------------------
00176 // 
00177 //-----------------------------------------------------------------------------
00178 const context::notation_decl_type& context::get_notation_decl(const xstring& name) const
00179 {
00180         notation_decl_map_type::const_iterator i(notations_decl_.find(name));
00181         if (i==notations_decl_.end()) {
00182                 static notation_decl_type sResult;
00183                 return sResult;
00184         }
00185         return i->second;
00186 }
00187 
00188 //-----------------------------------------------------------------------------
00189 // 
00190 //-----------------------------------------------------------------------------
00191 const xstring& context::get_entity(const xstring& entity_name) const
00192 {
00193         entity_def_map_type::const_iterator i(entities_.find(entity_name));
00194         if (i==entities_.end()) return entity_name;
00195         return i->second.entity_value;
00196 }
00197 
00198 //-----------------------------------------------------------------------------
00199 // 
00200 //-----------------------------------------------------------------------------
00201 const xstring& context::get_parameter_entity(const xstring& entity_name) const
00202 {
00203         pe_def_map_type::const_iterator i(parameter_entities_.find(entity_name));
00204         if (i==parameter_entities_.end()) return entity_name;
00205         return i->second.entity_value;
00206 }
00207 
00208 //-----------------------------------------------------------------------------
00209 // 
00210 //-----------------------------------------------------------------------------
00211 const xstring& context::get_processing_instruction(const xstring& pi_target) const
00212 {
00213         map_type::const_iterator i(processing_instructions_.find(pi_target));
00214         if (i==processing_instructions_.end()) return pi_target;
00215         return i->second;
00216 }
00217 
00218 //-----------------------------------------------------------------------------
00219 // 
00220 //-----------------------------------------------------------------------------
00221 const xstring& context::get_version_num           () const
00222 {
00223         return version_num_;
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 // 
00228 //-----------------------------------------------------------------------------
00229 bool context::get_sd_decl               () const
00230 {
00231         return standalone_decl_;
00232 }
00233 
00234 //-----------------------------------------------------------------------------
00235 // 
00236 //-----------------------------------------------------------------------------
00237 const xstring& context::get_encoding_decl         () const
00238 {
00239         return encoding_decl_;
00240 }
00241 
00242 //-----------------------------------------------------------------------------
00243 // 
00244 //-----------------------------------------------------------------------------
00245 void context::set_version_num  (const xstring& ver)
00246 {
00247         version_num_=ver;
00248 }
00249 
00250 //-----------------------------------------------------------------------------
00251 // 
00252 //-----------------------------------------------------------------------------
00253 void context::set_sd_decl      (bool           sddecl)
00254 {
00255         standalone_decl_=sddecl;
00256 }
00257 
00258 //-----------------------------------------------------------------------------
00259 // 
00260 //-----------------------------------------------------------------------------
00261 void context::set_encoding_decl(const xstring& encoding_name)
00262 {
00263         encoding_decl_=encoding_name;
00264 }
00265 
00266 //-----------------------------------------------------------------------------
00267 // 
00268 //-----------------------------------------------------------------------------
00269 context& context::add_new_level(const xstring& uri,
00270                                                           const xstring &tag, 
00271                                                           const XIMOL_XML_NAMESPACE_PATH::attributes& att, 
00272                                                       bool open_start, 
00273                                                       bool open_end)
00274 {
00275         level level;
00276         level.att_+=att;
00277         level.tag_=tag;
00278     level.uri_tag_ = uri;
00279 
00280         XIMOL_XML_NAMESPACE_PATH::attributes::const_ns_iterator itr_uri =
00281                 att.find_namespace(uri);
00282 
00283         if(itr_uri != att.ns_end())
00284                 level.uri_tag_ = itr_uri->first;
00285 
00286     if(level.uri_tag_ == uri) {
00287                 itr_uri = att.find_short_namespace(uri);
00288 
00289                 if(itr_uri != att.ns_end() && itr_uri->first == uri)
00290                     level.uri_tag_ = get_namespace(uri);
00291         }
00292 
00293         level.is_open_stag=open_start;
00294         level.is_open_etag=open_end;
00295 
00296         levels_.push_back(level);
00297         return *this;
00298 }
00299 
00300 //-----------------------------------------------------------------------------
00301 // 
00302 //-----------------------------------------------------------------------------
00303 context& context::destroy_level()
00304 {
00305         if (get_depth()>0)
00306                 levels_.pop_back();
00307         return *this;
00308 }
00309 
00310 //-----------------------------------------------------------------------------
00311 // 
00312 //-----------------------------------------------------------------------------
00313 bool context::is_open_stag() const
00314 {
00315         if (get_depth()>0)
00316                 return levels_.back().is_open_stag;
00317         return false;
00318 }
00319 
00320 //-----------------------------------------------------------------------------
00321 // 
00322 //-----------------------------------------------------------------------------
00323 bool context::is_open_etag() const
00324 {
00325         if (get_depth()>0)
00326                 return levels_.back().is_open_etag;
00327         return false;
00328 }
00329 
00330 //-----------------------------------------------------------------------------
00331 // 
00332 //-----------------------------------------------------------------------------
00333 context& context::close_open_stag()
00334 {
00335         if (get_depth()>0)
00336                 levels_.back().is_open_stag=false;
00337         return *this;
00338 }
00339 
00340 //-----------------------------------------------------------------------------
00341 // 
00342 //-----------------------------------------------------------------------------
00343 context& context::close_open_etag()
00344 {
00345         if (get_depth()>0)
00346                 levels_.back().is_open_etag=false;
00347         return *this;
00348 }
00349 
00350 //-----------------------------------------------------------------------------
00351 // 
00352 //-----------------------------------------------------------------------------
00353 context& context::set_open_stag()
00354 {
00355         if (get_depth()>0)
00356                 levels_.back().is_open_stag=true;
00357         return *this;
00358 }
00359 
00360 //-----------------------------------------------------------------------------
00361 // 
00362 //-----------------------------------------------------------------------------
00363 context& context::set_open_etag()
00364 {
00365         if (get_depth()>0)
00366                 levels_.back().is_open_etag=true;
00367         return *this;
00368 }
00369 
00370 //-----------------------------------------------------------------------------
00371 // 
00372 //-----------------------------------------------------------------------------
00373 const xstring & context::get_level_tag() const
00374 {
00375         if (get_depth()==0) 
00376                 XIMOL_THROW << _(L"There is no tag") << XIMOL_AS_ERROR;
00377 
00378         return levels_.back().tag_;
00379 }
00380 
00381 //-----------------------------------------------------------------------------
00382 // 
00383 //-----------------------------------------------------------------------------
00384 const xstring & context::get_level_short_ns_tag() const
00385 {
00386         if (get_depth()==0) 
00387                 XIMOL_THROW << _(L"There is no namespace tag") << XIMOL_AS_ERROR;
00388 
00389         return get_short_namespace(levels_.back().uri_tag_);
00390 }
00391 
00392 //-----------------------------------------------------------------------------
00393 // 
00394 //-----------------------------------------------------------------------------
00395 const xstring & context::get_level_ns_tag() const
00396 {
00397         if (get_depth()==0) 
00398                 XIMOL_THROW << _(L"There is no namespace tag") << XIMOL_AS_ERROR;
00399 
00400         return levels_.back().uri_tag_;
00401 }
00402 
00403 //-----------------------------------------------------------------------------
00404 // 
00405 //-----------------------------------------------------------------------------
00406 const XIMOL_XML_NAMESPACE_PATH::attributes & context::get_level_attributes() const
00407 {
00408         if (get_depth()==0) 
00409                 XIMOL_THROW << "There is no attributes" << XIMOL_AS_ERROR;
00410                 
00411         return levels_.back().att_;
00412 }
00413 
00414 //-----------------------------------------------------------------------------
00415 // 
00416 //-----------------------------------------------------------------------------
00417 XIMOL_XML_NAMESPACE_PATH::attributes context::get_attributes() const
00418 {
00419         levels_type::const_reverse_iterator i(levels_.rbegin()), i_end(levels_.rend());
00420         XIMOL_XML_NAMESPACE_PATH::attributes result;
00421         for(;i!=i_end;++i) 
00422                 result+=i->att_;
00423         return result;
00424 }
00425 
00426 //-----------------------------------------------------------------------------
00427 // 
00428 //-----------------------------------------------------------------------------
00429 int context::get_depth() const
00430 {
00431         if (levels_.empty()) return 0;
00432         return static_cast<int>(levels_.size());
00433 }
00434 
00435 //-----------------------------------------------------------------------------
00436 // 
00437 //-----------------------------------------------------------------------------
00438 context& context::add_level_attributes(const XIMOL_XML_NAMESPACE_PATH::attributes & att)
00439 {
00440         if (get_depth()>0)
00441                 levels_.back().att_+=att;
00442         return *this;
00443 }
00444 
00445 //-----------------------------------------------------------------------------
00446 // 
00447 //-----------------------------------------------------------------------------
00448 const xstring& context::get_namespace(const xstring &short_ns) const
00449 {
00450         levels_type::const_reverse_iterator i = levels_.rbegin();
00451         levels_type::const_reverse_iterator const i_end = levels_.rend();
00452         XIMOL_XML_NAMESPACE_PATH::attributes::const_ns_iterator i_uri;
00453         while(i != i_end && (i_uri = i->att_.find_namespace(short_ns)) == i->att_.ns_end()) ++i;
00454 
00455         if(i == i_end) return short_ns;
00456 
00457         static xstring const str_empty;
00458         return i_uri != i->att_.ns_end()
00459                 ? i_uri->first
00460                 : str_empty;
00461 }
00462 
00463 //-----------------------------------------------------------------------------
00464 // 
00465 //-----------------------------------------------------------------------------
00466 const xstring& context::get_short_namespace(const xstring &uri) const
00467 {       
00468         if (uri.empty()) return uri;
00469 
00470         levels_type::const_reverse_iterator i = levels_.rbegin();
00471         levels_type::const_reverse_iterator const i_end = levels_.rend();
00472         XIMOL_XML_NAMESPACE_PATH::attributes::const_ns_iterator i_short;
00473         while ( (i != i_end) && 
00474             ((i_short = i->att_.find_short_namespace(uri)) == i->att_.ns_end())
00475            ) ++i;
00476 
00477         if(i == i_end) return uri;
00478 
00479         static xstring const str_empty;
00480         return i_short != i->att_.ns_end()
00481                 ? i_short->second
00482                 : str_empty;
00483 }
00484 
00485 //-----------------------------------------------------------------------------
00486 // 
00487 //-----------------------------------------------------------------------------
00488 const xstring& context::get_default_namespace() const
00489 {
00490         levels_type::const_reverse_iterator i = levels_.rbegin();
00491         levels_type::const_reverse_iterator const i_end = levels_.rend();
00492         XIMOL_XML_NAMESPACE_PATH::attributes::const_ns_iterator i_default;
00493         while(i != i_end && (i_default = i->att_.find_namespace()) == i->att_.ns_end()) ++i;
00494 
00495         static xstring const str_empty;
00496         if(i == i_end) return str_empty;
00497 
00498         return i_default != i->att_.ns_end()
00499                 ? i_default->second
00500                 : str_empty;
00501 }
00502 
00503 //-----------------------------------------------------------------------------
00504 // 
00505 //-----------------------------------------------------------------------------
00506 const xstring & context::get_doc_type_name() const
00507 {
00508         return doctype_name_;
00509 }
00510 
00511 //-----------------------------------------------------------------------------
00512 // 
00513 //-----------------------------------------------------------------------------
00514 void context::set_doc_type_name(const xstring& name)
00515 {
00516         doctype_name_=name;
00517 }
00518 
00519 //-----------------------------------------------------------------------------
00520 // 
00521 //-----------------------------------------------------------------------------
00522 const context::notation_decl_type & context::get_doctype_external_id() const
00523 {
00524         return doctype_external_id_;
00525 }
00526 
00527 //-----------------------------------------------------------------------------
00528 // 
00529 //-----------------------------------------------------------------------------
00530 void context::set_doctype_external_id(const xstring& system_literal, const xstring& pubid_literal)
00531 {
00532         doctype_external_id_.system_literal_=system_literal;
00533         doctype_external_id_.pubid_literal_=pubid_literal;
00534 }
00535 
00536 XIMOL_XML_END_NAMESPACE


Donate to the XiMoL project SourceForge.net Logo If you have any questions about XiMoL, you could write to tournois@users.sourceforge.net.