使用Boost.PropertyTree

时间:2019-05-24 09:46:40

标签: c++ visual-studio-2010 boost

我有以下示例XML文件:

<?xml version="1.0" ?>
<Root>
  <ChildArray>
    1.0  0.0 -1.0
  </ChildArray>
</Root>

我正在尝试使用Boost.PropertyTree读取它,请尝试以下操作:

#include <array>
#include <string>
#include <iostream>
#include <exception>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

namespace pt = boost::property_tree;

struct VectorXML
{
    std::array<float, 3> _data;
    void load(const std::string &filename);
};

void VectorXML::load(const std::string &filename)
{
    // Create empty property tree object
    pt::ptree tree;

    // Parse the XML into the property tree.
    pt::read_xml(filename, tree);

    _data=
        tree.get<std::array<float, 3>>("Root.ChildArray");
}

int main()
{
    try
    {
        VectorXML v;
        v.load("data.xml");
        std::cout << "Success\n";
        std::cout
            << "X: " << v._data[0] << " "
            << "Y: " << v._data[1] << " "
            << "Z: " << v._data[2] << "\n";
    }
    catch (std::exception &e)
    {
        std::cout << "Error: " << e.what() << "\n";
    }
    return 0;
}

但是它无法编译(>>中的stream_translator.hpp重载不接受std::array s)。

我想我将不得不手动遍历数据,但是我无法提出从该节点检索数据的方法,有关如何访问值大于1的节点中的数据的文档尚不清楚。

类似

for (size_t i = 0; i < 3; ++i)
    _data[i] = tree.get<float>("Root.ChildMatrix.???");

但是它不起作用(节点具有3个浮点,并且boost无法转换为“ float”)。

1 个答案:

答案 0 :(得分:0)

好吧,这很简单,我是白痴,因为没有尝试更多。我不会将其标记为 如果有人发布更好的答案,该答案。

我已经扩展了答案,以适应任意维度的矩阵(假设您 将属性Size="M N"添加到节点)。

回答原始问题

std::stringstream iss(
    tree.get_child("Root.ChildArray")
        .data() // string
);
float number = 0;
for (size_t i = 0; i < 3; i++)
    if (iss >> number)
        _data[i] = number;

扩展答案

在这里,我添加了一个属性检查以读取尺寸(请注意,这可以是 进行了改进,尤其是对于更大的尺寸,并且该模型仍使用 array<float,3>,而不是完全动态的容器。

// probably can be done in a more elegant way
std::stringstream iss(
    tree.get<std::string>("Root.ChildArray.<xmlattr>.Dimensions")
);
size_t M = 0;
iss >> M;
// *********
iss.str(
    tree.get_child("Root.ChildArray")
        .data()
);
_data.resize(M);
float number = 0;
for (size_t row = 0; row < M; row++)
{
    for (size_t col = 0; col < 3; col++)
    {
        if (iss >> number)
        {
            _data[row][col] = number;
        }
    }
}

尝试使用以下XML:

<?xml version="1.0" ?>
<Root>
  <ChildArray Dimensions="2 3">
    1.0  0.0 -1.0
    0.0  0.4  1.0
  </ChildArray>
</Root>