1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
11 #define BOOST_PROPERTY_TREE_DETAIL_XML_PARSER_WRITE_HPP_INCLUDED
13 #include <boost/property_tree/ptree.hpp>
14 #include <boost/property_tree/detail/xml_parser_utils.hpp>
19 namespace boost
{ namespace property_tree
{ namespace xml_parser
22 void write_xml_indent(std::basic_ostream
<Ch
> &stream
,
24 const xml_writer_settings
<Ch
> & settings
27 stream
<< std::basic_string
<Ch
>(indent
* settings
.indent_count
, settings
.indent_char
);
31 void write_xml_comment(std::basic_ostream
<Ch
> &stream
,
32 const std::basic_string
<Ch
> &s
,
34 const xml_writer_settings
<Ch
> & settings
37 typedef typename
std::basic_string
<Ch
> Str
;
38 write_xml_indent(stream
,indent
,settings
);
39 stream
<< Ch('<') << Ch('!') << Ch('-') << Ch('-');
41 stream
<< Ch('-') << Ch('-') << Ch('>') << std::endl
;
45 void write_xml_text(std::basic_ostream
<Ch
> &stream
,
46 const std::basic_string
<Ch
> &s
,
49 const xml_writer_settings
<Ch
> & settings
53 write_xml_indent(stream
,indent
,settings
);
54 stream
<< encode_char_entities(s
);
60 void write_xml_element(std::basic_ostream
<typename
Ptree::key_type::value_type
> &stream
,
61 const std::basic_string
<typename
Ptree::key_type::value_type
> &key
,
64 const xml_writer_settings
<typename
Ptree::key_type::value_type
> & settings
)
67 typedef typename
Ptree::key_type::value_type Ch
;
68 typedef typename
std::basic_string
<Ch
> Str
;
69 typedef typename
Ptree::const_iterator It
;
71 // Find if elements present
72 bool has_elements
= false;
73 bool has_attrs_only
= pt
.data().empty();
74 for (It it
= pt
.begin(), end
= pt
.end(); it
!= end
; ++it
)
76 if (it
->first
!= xmlattr
<Ch
>() )
78 has_attrs_only
= false;
79 if (it
->first
!= xmltext
<Ch
>())
88 if (pt
.data().empty() && pt
.empty()) // Empty key
92 write_xml_indent(stream
,indent
,settings
);
93 stream
<< Ch('<') << key
<<
94 Ch('/') << Ch('>') << std::endl
;
100 // Write opening tag, attributes and data
104 // Write opening brace and key
105 write_xml_indent(stream
,indent
,settings
);
106 stream
<< Ch('<') << key
;
109 if (optional
<const Ptree
&> attribs
= pt
.get_child_optional(xmlattr
<Ch
>()))
110 for (It it
= attribs
.get().begin(); it
!= attribs
.get().end(); ++it
)
111 stream
<< Ch(' ') << it
->first
<< Ch('=') <<
112 Ch('"') << it
->second
.template get_value
<std::basic_string
<Ch
> >() << Ch('"');
114 if ( has_attrs_only
)
116 // Write closing brace
117 stream
<< Ch('/') << Ch('>') << std::endl
;
121 // Write closing brace
124 // Break line if needed
130 // Write data text, if present
131 if (!pt
.data().empty())
132 write_xml_text(stream
, pt
.template get_value
<std::basic_string
<Ch
> >(), indent
+ 1, has_elements
, settings
);
134 // Write elements, comments and texts
135 for (It it
= pt
.begin(); it
!= pt
.end(); ++it
)
137 if (it
->first
== xmlattr
<Ch
>())
139 else if (it
->first
== xmlcomment
<Ch
>())
140 write_xml_comment(stream
, it
->second
.template get_value
<std::basic_string
<Ch
> >(), indent
+ 1, settings
);
141 else if (it
->first
== xmltext
<Ch
>())
142 write_xml_text(stream
, it
->second
.template get_value
<std::basic_string
<Ch
> >(), indent
+ 1, has_elements
, settings
);
144 write_xml_element(stream
, it
->first
, it
->second
, indent
+ 1, settings
);
148 if (indent
>= 0 && !has_attrs_only
)
151 write_xml_indent(stream
,indent
,settings
);
152 stream
<< Ch('<') << Ch('/') << key
<< Ch('>') << std::endl
;
158 template<class Ptree
>
159 void write_xml_internal(std::basic_ostream
<typename
Ptree::key_type::value_type
> &stream
,
161 const std::string
&filename
,
162 const xml_writer_settings
<typename
Ptree::key_type::value_type
> & settings
)
164 typedef typename
Ptree::key_type::value_type Ch
;
165 typedef typename
std::basic_string
<Ch
> Str
;
166 stream
<< detail::widen
<Ch
>("<?xml version=\"1.0\" encoding=\"")
168 << detail::widen
<Ch
>("\"?>\n");
169 write_xml_element(stream
, Str(), pt
, -1, settings
);
171 BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename
, 0));