fix doc example typo
[boost.git] / boost / property_tree / detail / xml_parser_write.hpp
blob77853a8903eff35688c1245fe4d51f18d2cc24fc
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2006 Marcin Kalicinski
3 //
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)
7 //
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>
15 #include <string>
16 #include <ostream>
17 #include <iomanip>
19 namespace boost { namespace property_tree { namespace xml_parser
21 template<class Ch>
22 void write_xml_indent(std::basic_ostream<Ch> &stream,
23 int indent,
24 const xml_writer_settings<Ch> & settings
27 stream << std::basic_string<Ch>(indent * settings.indent_count, settings.indent_char);
30 template<class Ch>
31 void write_xml_comment(std::basic_ostream<Ch> &stream,
32 const std::basic_string<Ch> &s,
33 int indent,
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('-');
40 stream << s;
41 stream << Ch('-') << Ch('-') << Ch('>') << std::endl;
44 template<class Ch>
45 void write_xml_text(std::basic_ostream<Ch> &stream,
46 const std::basic_string<Ch> &s,
47 int indent,
48 bool separate_line,
49 const xml_writer_settings<Ch> & settings
52 if (separate_line)
53 write_xml_indent(stream,indent,settings);
54 stream << encode_char_entities(s);
55 if (separate_line)
56 stream << Ch('\n');
59 template<class Ptree>
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,
62 const Ptree &pt,
63 int indent,
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>())
81 has_elements = true;
82 break;
87 // Write element
88 if (pt.data().empty() && pt.empty()) // Empty key
90 if (indent >= 0)
92 write_xml_indent(stream,indent,settings);
93 stream << Ch('<') << key <<
94 Ch('/') << Ch('>') << std::endl;
97 else // Nonempty key
100 // Write opening tag, attributes and data
101 if (indent >= 0)
104 // Write opening brace and key
105 write_xml_indent(stream,indent,settings);
106 stream << Ch('<') << key;
108 // Write attributes
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;
119 else
121 // Write closing brace
122 stream << Ch('>');
124 // Break line if needed
125 if (has_elements)
126 stream << Ch('\n');
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>())
138 continue;
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);
143 else
144 write_xml_element(stream, it->first, it->second, indent + 1, settings);
147 // Write closing tag
148 if (indent >= 0 && !has_attrs_only)
150 if (has_elements)
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,
160 const Ptree &pt,
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=\"")
167 << settings.encoding
168 << detail::widen<Ch>("\"?>\n");
169 write_xml_element(stream, Str(), pt, -1, settings);
170 if (!stream)
171 BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0));
174 } } }
176 #endif