00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
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
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"<");
00106 add_entity(L"gt" , L">");
00107 add_entity(L"amp" , L"&");
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