Better XML formatting using Boost?

949 views Asked by At

I'm using Boost Property Trees to export my class-instants as XML nodes. It works but it just puts everything in 1 line. I would like it to have indents, like:

<?xml version="1.0" encoding="utf-8"?>
<root>
<sensorconfigurations>
    <configuration>
        <name>SensorConfiguration1</name>
        <sensorid>1</sensorid>
        <signalindex>1</signalindex>
        <mappingscheme>mappingscheme1</mappingscheme>
        <soundpack>test1.wav</soundpack>
    </configuration>
    <configuration>
        <name>SensorConfiguration2</name>
        <sensorid>2</sensorid>
        <signalindex>2</signalindex>
        <mappingscheme>mappingscheme1</mappingscheme>
        <soundpack>test2.wav</soundpack>
    </configuration>
    <configuration>
        <name>SensorConfiguration3</name>
        <sensorid>3</sensorid>
        <signalindex>3</signalindex>
        <mappingscheme>mappingscheme2</mappingscheme>
        <soundpack>test3.wav</soundpack>
    </configuration>
</sensorconfigurations>
</root>

Is this possible somehow? Am I missing a parameter in the write_xml method?

Here's my code:

void SensorConfigurationBank::save()
{
using boost::property_tree::ptree;
ptree pt;
for(map<string, SensorConfiguration>:: iterator it = sensorConfigurations_.begin(); it != sensorConfigurations_.end(); ++it) 
{
    ptree myTree;
    myTree.put("name", it->second.getName());
    myTree.put("sensorid", it->second.getSensorID());
    myTree.put("signalindex", it->second.getsignalIndex());
    MappingScheme myScheme = it->second.getMScheme();
    myTree.put("mappingscheme", myScheme.getId());
    SoundPack mySound = it->second.getSound();
    myTree.put("soundpack", mySound.filepath_);

    pt.add_child("root.sensorconfigurations.configuration", myTree);
}
write_xml("SensorConfigurationBank2.xml", pt); 
}
1

There are 1 answers

0
sehe On BEST ANSWER

These days, xml_writer_settings apparently takes a string type as template argument, so:

boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
write_xml(std::cout, pt, settings); 

will do the trick. Full sample:

Live On Coliru

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

struct SoundPack {
    std::string filepath_ = "soundpack.wav";
};
struct MappingScheme {
    std::string getId()    const { return "Id";    }
};
struct SensorConfiguration {
    std::string   getName()        const { return "Name";        }
    std::string   getSensorID()    const { return "SensorID";    }
    std::string   getsignalIndex() const { return "signalIndex"; }
    SoundPack     getSound()       const { return {};            }
    MappingScheme getMScheme()     const { return {};            }
};

void save(std::map<std::string, SensorConfiguration> sensorConfigurations_)
{
    using boost::property_tree::ptree;
    ptree pt;
    for(std::map<std::string, SensorConfiguration>:: iterator it = sensorConfigurations_.begin(); it != sensorConfigurations_.end(); ++it) 
    {
        ptree myTree;

        MappingScheme myScheme = it->second.getMScheme();
        SoundPack mySound = it->second.getSound();

        myTree.put("name",          it->second.getName());
        myTree.put("sensorid",      it->second.getSensorID());
        myTree.put("signalindex",   it->second.getsignalIndex());
        myTree.put("mappingscheme", myScheme.getId());
        myTree.put("soundpack",     mySound.filepath_);

        pt.add_child("root.sensorconfigurations.configuration", myTree);
    }
    boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
    write_xml(std::cout, pt, settings); 
}

int main() {
    save({
            { "first",  SensorConfiguration {} },
            { "second", SensorConfiguration {} },
            { "third",  SensorConfiguration {} },
            { "fourth", SensorConfiguration {} }
        });
}

Output:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <sensorconfigurations>
        <configuration>
            <name>Name</name>
            <sensorid>SensorID</sensorid>
            <signalindex>signalIndex</signalindex>
            <mappingscheme>Id</mappingscheme>
            <soundpack>soundpack.wav</soundpack>
        </configuration>
        <configuration>
            <name>Name</name>
            <sensorid>SensorID</sensorid>
            <signalindex>signalIndex</signalindex>
            <mappingscheme>Id</mappingscheme>
            <soundpack>soundpack.wav</soundpack>
        </configuration>
        <configuration>
            <name>Name</name>
            <sensorid>SensorID</sensorid>
            <signalindex>signalIndex</signalindex>
            <mappingscheme>Id</mappingscheme>
            <soundpack>soundpack.wav</soundpack>
        </configuration>
        <configuration>
            <name>Name</name>
            <sensorid>SensorID</sensorid>
            <signalindex>signalIndex</signalindex>
            <mappingscheme>Id</mappingscheme>
            <soundpack>soundpack.wav</soundpack>
        </configuration>
    </sensorconfigurations>
</root>