2011-07-04 3 views
27

J'utilise boost :: property_tree pour lire et écrire des fichiers de configuration XML dans mon application. Mais quand j'écris le fichier, la sortie semble plutôt moche avec beaucoup de lignes vides dans le fichier. Le problème est qu'il est supposé être édité par des humains aussi, donc j'aimerais avoir un meilleur résultat.boost :: property_tree XML jolie impression

À titre d'exemple, j'ai écrit un petit programme de test:

#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 contient:

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

après l'exécution du programme file2.xml contient:

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



    <net> 



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

Est Y at-il un moyen d'avoir une meilleure sortie, autre que d'aller manuellement à travers la sortie et la suppression des lignes vides?

+2

boost :: property_tree utilise un analyseur XML appelé RapidXML, http://rapidxml.sourceforge.net/. Les deux boost :: property_tree et RapidXML sont maintenus par Marcin Kalicinski. Je vous suggère de le contacter directement. Vous pouvez trouver son adresse mail sur la page d'accueil de RapidXML. – user763305

+0

merci ildjarn pour l'édition, mais les lignes vides sont là pour une raison!Btw question posée au mainteneur, je posterai la réponse s'il y en a une – foke

Répondre

39

La solution a été d'ajouter le drapeau trim_whitespace à l'appel à 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; 
} 

Le drapeau est documenté here mais le responsable actuel de la bibliothèque (Sébastien Redl) a eu la gentillesse de répondre et me pointer vers il.

+1

Attention: trim_whitespace non seulement supprime les espaces dans le XML, mais aussi les espaces dans tout élément qui ne contient pas d'autres éléments: ' xx' est lu comme si c'était « xx». –

+7

Il est étrange que l'on doive modifier les paramètres * read * pour l'obtenir (spécialement après le commentaire @AndreasHaferburg). Quoi qu'il en soit, dans la version actuelle de Boost, il faut utiliser 'xml_writer_settings ' (pas 'char'). – alfC

+0

mis à jour lien "ici": http://www.boost.org/doc/libs/1_58_0/doc/html/boost/property_tree/xml_parser/read_xml_idp82929296.html – alfC

3

Cette question est assez vieux, mais j'étudié à nouveau votre problème, ces derniers temps, parce qu'il a bien pire maintenant que property_tree se traduit par des sauts de ligne à

À mon avis, c'est un bug, parce que les éléments qui contient uniquement des espaces: les retours à la ligne, les espaces et les tabulations sont traités comme des éléments de texte. trim_whitespace est seulement un bandaid et normalise TOUS les espaces dans le property_tree.

J'ai signalé le bug ici et aussi attaché un .diff pour corriger ce comportement dans Boost 1,59 en cas trim_whitespace n'est pas utilisé: https://svn.boost.org/trac/boost/ticket/11600

2

Pour ceux qui cherchent:

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

avec boost Compiler -1.60.0 à VisualStudio 2013 vous pouvez obtenir:

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 

ici fin Puis:

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

Solution pour fonder le travail est d'utiliser std :: string dans le modèle.

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

comme décrit ici:

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

Questions connexes