2011-07-04 9 views
27

Estoy usando boost :: property_tree para leer y escribir archivos de configuración XML en mi aplicación. Pero cuando escribo el archivo, el resultado se ve feo con muchas líneas vacías en el archivo. El problema es que se supone que también debe ser editado por humanos, por lo que me gustaría obtener un mejor resultado.boost :: property_tree XML pretty printing

Como ejemplo he escrito un pequeño programa de prueba:

#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 

int main(void) 
{ 
    using boost::property_tree::ptree; 
    ptree pt; 

    // reading file.xml 
    read_xml("file.xml", pt); 

    // writing the unchanged ptree in file2.xml 
    boost::property_tree::xml_writer_settings<char> settings('\t', 1); 
    write_xml("file2.xml", pt, std::locale(), settings); 

    return 0; 
} 

file.xml contiene:

<?xml version="1.0" ?> 
<config> 
    <net> 
     <listenPort>10420</listenPort> 
    </net> 
</config> 

después de ejecutar el programa de file2.xml contiene:

<?xml version="1.0" encoding="utf-8"?> 
<config> 



    <net> 



     <listenPort>10420</listenPort> 
    </net> 
</config> 

Es Hay una manera de tener una mejor salida, que no sea pasar manualmente a través de la salida y eliminar las líneas vacías?

+2

impulso :: property_tree utiliza un analizador XML llamado RapidXML, http://rapidxml.sourceforge.net/. Both boost :: property_tree y RapidXML son mantenidos por Marcin Kalicinski. Sugiero que lo contactes directamente. Puede encontrar su dirección de correo electrónico en la página de inicio de RapidXML. – user763305

+0

gracias ildjarn por la edición, pero las líneas vacías están aquí por una razón.Por cierto pregunta al mantenedor, publicaré la respuesta si hay una – foke

Respuesta

39

La solución fue añadir la bandera trim_whitespace a la llamada a read_xml:

#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/xml_parser.hpp> 

int main(void) 
{ 
    // Create an empty property tree object 
    using boost::property_tree::ptree; 
    ptree pt; 

    // reading file.xml 
    read_xml("file.xml", pt, boost::property_tree::xml_parser::trim_whitespace); 

    // writing the unchanged ptree in file2.xml 
    boost::property_tree::xml_writer_settings<char> settings('\t', 1); 
    write_xml("file2.xml", pt, std::locale(), settings); 

    return 0; 
} 

La bandera está documentado here pero el encargado actual de la biblioteca (Sebastien Redl) tuvo la amabilidad de contestar y me señale eso.

+1

Advertencia: trim_whitespace no solo recorta el espacio en blanco en el XML, sino también el espacio en blanco en cualquier elemento que no contenga otros elementos: ' xx' es leído como si fuera ' xx'. –

+7

Es extraño que haya que cambiar la configuración * read * para obtener esto (especialmente después del comentario de @AndreasHaferburg). De todos modos en la versión actual de Boost uno necesita usar 'xml_writer_settings ' (no 'char'). – alfC

+0

se ha actualizado el enlace "aquí": http://www.boost.org/doc/libs/1_58_0/doc/html/boost/property_tree/xml_parser/read_xml_idp82929296.html – alfC

3

Esta pregunta es bastante antiguo, pero me investigó el problema de nuevo, últimamente, porque se hacía mucho peor ahora que property_tree traduce nuevas líneas de

En mi opinión, esto es un error, ya que los elementos, los cuales contiene solo espacios en blanco: nuevas líneas, espacios y pestañas se tratan como elementos de texto. trim_whitespace es solo un bandaid y normaliza TODOS los espacios en blanco en el property_tree.

que informó del fallo aquí y también unida una .diff para corregir este comportamiento en Boost 1,59 en el caso trim_whitespace no se utiliza: https://svn.boost.org/trac/boost/ticket/11600

2

Para aquellos que tratan:

boost::property_tree::xml_writer_settings<char> settings('\t', 1); 

Compilar con impulso -1.60.0 en VisualStudio 2013 puede obtener:

vmtknetworktest.cpp(259) : see reference to class template instantiation 'boost::property_tree::xml_parser::xml_writer_settings<char>' being compiled 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C2039: 'value_type' : is not a member of '`global namespace'' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C2146: syntax error : missing ';' before identifier 'Ch' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(38): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(40): error C2061: syntax error : identifier 'Ch' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(49): error C2146: syntax error : missing ';' before identifier 'indent_char' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(49): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2825: 'Str': must be a class or namespace when followed by '::' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2039: 'size_type' : is not a member of '`global namespace'' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C2146: syntax error : missing ';' before identifier 'indent_count' 
install\include\boost-1_60\boost/property_tree/detail/xml_parser_writer_settings.hpp(50): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
vmtknetworktest.cpp(259): error C2661: 'boost::property_tree::xml_parser::xml_writer_settings<char>::xml_writer_settings' : no overloaded function takes 3 arguments 

luego terminan aquí:

https://svn.boost.org/trac/boost/ticket/10272

Solución al descubierto que el trabajo es utilizar std :: string en la plantilla.

pt::write_xml(file_name, params, std::locale(), pt::xml_writer_make_settings<std::string>(' ', 4)); 

como se describe aquí:

https://stackoverflow.com/a/35043551/7170333