void write_xml_internal(std::basic_ostream<typename Ptree::char_type> &stream, const Ptree &pt, const std::string &filename) { typedef typename Ptree::char_type Ch; typedef typename std::basic_string<Ch> Str; stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); write_xml_element(stream, Str(), pt, -1); if (!stream) throw xml_parser_error("write error", filename, 0); }
void write_xml_internal(std::basic_ostream<typename Ptree::key_type::value_type> &stream, const Ptree &pt, const std::string &filename, const xml_writer_settings<typename Ptree::key_type::value_type> & settings) { typedef typename Ptree::key_type::value_type Ch; typedef typename std::basic_string<Ch> Str; stream << detail::widen<Ch>("<?xml version=\"1.0\" encoding=\"") << settings.encoding << detail::widen<Ch>("\"?>\n"); write_xml_element(stream, Str(), pt, -1, settings); if (!stream) BOOST_PROPERTY_TREE_THROW(xml_parser_error("write error", filename, 0)); }
void write_xml_element(std::basic_ostream<typename Ptree::key_type::value_type> &stream, const std::basic_string<typename Ptree::key_type::value_type> &key, const Ptree &pt, int indent, const xml_writer_settings<typename Ptree::key_type::value_type> & settings) { typedef typename Ptree::key_type::value_type Ch; typedef typename Ptree::const_iterator It; bool want_pretty = settings.indent_count > 0; // Find if elements present bool has_elements = false; bool has_attrs_only = pt.data().empty(); for (It it = pt.begin(), end = pt.end(); it != end; ++it) { if (it->first != xmlattr<Ch>() ) { has_attrs_only = false; if (it->first != xmltext<Ch>()) { has_elements = true; break; } } } // Write element if (pt.data().empty() && pt.empty()) // Empty key { if (indent >= 0) { write_xml_indent(stream,indent,settings); stream << Ch('<') << key << Ch('/') << Ch('>'); if (want_pretty) stream << Ch('\n'); } } else // Nonempty key { // Write opening tag, attributes and data if (indent >= 0) { // Write opening brace and key write_xml_indent(stream,indent,settings); stream << Ch('<') << key; // Write attributes if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>())) for (It it = attribs.get().begin(); it != attribs.get().end(); ++it) stream << Ch(' ') << it->first << Ch('=') << Ch('"') << encode_char_entities( it->second.template get_value<std::basic_string<Ch> >()) << Ch('"'); if ( has_attrs_only ) { // Write closing brace stream << Ch('/') << Ch('>'); if (want_pretty) stream << Ch('\n'); } else { // Write closing brace stream << Ch('>'); // Break line if needed and if we want pretty-printing if (has_elements && want_pretty) stream << Ch('\n'); } } // Write data text, if present if (!pt.data().empty()) write_xml_text(stream, pt.template get_value<std::basic_string<Ch> >(), indent + 1, has_elements && want_pretty, settings); // Write elements, comments and texts for (It it = pt.begin(); it != pt.end(); ++it) { if (it->first == xmlattr<Ch>()) continue; else if (it->first == xmlcomment<Ch>()) write_xml_comment(stream, it->second.template get_value<std::basic_string<Ch> >(), indent + 1, want_pretty, settings); else if (it->first == xmltext<Ch>()) write_xml_text(stream, it->second.template get_value<std::basic_string<Ch> >(), indent + 1, has_elements && want_pretty, settings); else write_xml_element(stream, it->first, it->second, indent + 1, settings); } // Write closing tag if (indent >= 0 && !has_attrs_only) { if (has_elements) write_xml_indent(stream,indent,settings); stream << Ch('<') << Ch('/') << key << Ch('>'); if (want_pretty) stream << Ch('\n'); } } }
void write_xml_element(std::basic_ostream<typename Ptree::char_type> &stream, const std::basic_string<typename Ptree::char_type> &key, const Ptree &pt, int indent) { typedef typename Ptree::char_type Ch; typedef typename std::basic_string<Ch> Str; typedef typename Ptree::const_iterator It; // Find if elements present bool has_elements = false; for (It it = pt.begin(), end = pt.end(); it != end; ++it) if (it->first != xmlattr<Ch>() && it->first != xmltext<Ch>()) { has_elements = true; break; } // Write element if (pt.data().empty() && pt.empty()) // Empty key { if (indent >= 0) stream << Str(4 * indent, Ch(' ')) << Ch('<') << key << Ch('/') << Ch('>') << std::endl; } else // Nonempty key { // Write opening tag, attributes and data if (indent >= 0) { // Write opening brace and key stream << Str(4 * indent, Ch(' ')); stream << Ch('<') << key; // Write attributes if (optional<const Ptree &> attribs = pt.get_child_optional(xmlattr<Ch>())) for (It it = attribs.get().begin(); it != attribs.get().end(); ++it) stream << Ch(' ') << it->first << Ch('=') << Ch('"') << it->second.template get_own<std::basic_string<Ch> >() << Ch('"'); // Write closing brace stream << Ch('>'); // Break line if needed if (has_elements) stream << Ch('\n'); } // Write data text, if present if (!pt.data().empty()) write_xml_text(stream, pt.template get_own<std::basic_string<Ch> >(), indent + 1, has_elements); // Write elements, comments and texts for (It it = pt.begin(); it != pt.end(); ++it) { if (it->first == xmlattr<Ch>()) continue; else if (it->first == xmlcomment<Ch>()) write_xml_comment(stream, it->second.template get_own<std::basic_string<Ch> >(), indent + 1); else if (it->first == xmltext<Ch>()) write_xml_text(stream, it->second.template get_own<std::basic_string<Ch> >(), indent + 1, has_elements); else write_xml_element(stream, it->first, it->second, indent + 1); } // Write closing tag if (indent >= 0) { if (has_elements) stream << Str(4 * indent, Ch(' ')); stream << Ch('<') << Ch('/') << key << Ch('>') << std::endl; } } }