00001
#ifndef simplexml_SERIALIZER_H_INCLUDED
00002
#define simplexml_SERIALIZER_H_INCLUDED 1
00003
00004
00005
00006
00007
00008
00009
00010
00011
#define MAGIC_COOKIE_SIMPLEXML "<!DOCTYPE s11n::simplexml>"
00012
00013
namespace s11n {
00014
namespace io {
00015
00016
00017
00018
00019
00020
00021
00022
00023
namespace sharing {
00024
00025
00026
00027 struct simplexml_sharing_context {};
00028 }
00029
typedef std::map<std::string,std::string>
entity_translation_map;
00030
00031
00032
00033
00034
entity_translation_map &
simplexml_serializer_translations();
00035
00036
00037
00038
00039
#define TAB(LEVEL,ECHO) indent = ""; for( size_t i = 0; i < depth + LEVEL; i++ ) { indent += '\t'; if(ECHO) dest << '\t'; }
00040
00041
00042
00043
00044
00045
00046
template <
typename NodeType>
00047 class simplexml_serializer :
public tree_builder_lexer<NodeType,sharing::simplexml_sharing_context>
00048 {
00049
public:
00050
typedef NodeType node_type;
00051
00052
typedef simplexml_serializer<node_type> this_type;
00053
typedef tree_builder_lexer<node_type,sharing::simplexml_sharing_context> parent_type;
00054
00055
simplexml_serializer() :
parent_type(
"simplexml_data_nodeFlexLexer" ), m_depth(0)
00056 {
00057 this->
magic_cookie( MAGIC_COOKIE_SIMPLEXML );
00058 }
00059
00060
virtual ~
simplexml_serializer() {}
00061
00062
00063
00064
00065
00066 virtual const entity_translation_map &
entity_translations()
const
00067
{
00068
return simplexml_serializer_translations();
00069 }
00070
00071
00072
00073
00074
00075 virtual bool serialize(
const node_type & src, std::ostream & dest )
00076 {
00077 size_t depth = this->m_depth++;
00078
if ( 0 == depth )
00079 {
00080 dest << this->
magic_cookie() <<
'\n';
00081 }
00082
00083
00084 std::string nname = src.name();
00085 std::string impl = src.impl_class();
00086 std::string indent;
00087
const entity_translation_map & trans = this->
entity_translations();
00088
00089 std::string ximpl = impl;
00090
s11n::translate_entities( ximpl, trans,
false );
00091
00092 TAB(0,1);
00093 dest <<
"<" << nname <<
" s11n_class=\"" << ximpl <<
"\"";
00094
00095 std::string propval;
00096 std::string key;
00097
00098
typename node_type::const_iterator it = src.begin(), et = src.end();
00099
if ( it != et )
00100 {
00101
for ( ; it != et; ++it )
00102 {
00103
if (
"CDATA" == ( *it ).first )
00104
continue;
00105 key = (*it).first;
00106 propval = (*it).second;
00107
s11n::translate_entities( propval, trans,
false );
00108 dest <<
" " << key <<
"=\"" << propval <<
"\"";
00109 }
00110 }
00111
00112
bool use_closer =
false;
00113
if ( src.is_set(
"CDATA" ) )
00114 {
00115 dest <<
">";
00116 use_closer =
true;
00117 dest <<
"<![CDATA[" << src.get_string(
"CDATA" ) <<
"]]>";
00118 }
00119
00120
00121
bool tailindent =
false;
00122
00123
if( src.children().end() != src.children().begin() )
00124 {
00125
if( ! use_closer ) dest << '>';
00126 use_closer =
true;
00127 tailindent =
true;
00128 dest <<
'\n';
00129 std::for_each( src.children().begin(),
00130 src.children().end(),
00131
node_child_simple_formatter<this_type>( *
this,
00132 dest,
00133
"",
00134
"" )
00135 );
00136 }
00137
00138 dest << ( tailindent ? indent :
"" );
00139
if( use_closer )
00140 {
00141 dest <<
"</" << nname << '>';
00142 }
00143
else
00144 {
00145 dest <<
" />";
00146 }
00147 dest <<
'\n';
00148
00149
if( 0 == depth )
00150 {
00151 dest.flush();
00152
00153 }
00154 --this->m_depth;
00155
return true;
00156 }
00157
00158
00159
private:
00160 size_t m_depth;
00161 };
00162
00163
00164 }
00165 }
00166
#undef TAB
00167
00168
#endif // simplexml_SERIALIZER_H_INCLUDED