Boost::property_tree:在 XML 解析器中使用 std::vector<> 在一个键中存储多个值

2023-12-30

我的问题与这个问题相关:Boost property_tree:每个键有多个值 https://stackoverflow.com/questions/13072704/boost-property-tree-multiple-values-per-key以及该问题之后的问题:Boost property_tree:模板类上每个键有多个值 https://stackoverflow.com/questions/29801003/boost-property-tree-multiple-values-per-key-on-a-template-class.

我正在尝试解析一个 XML 文件,其中多个值在单个键值处列出,使用std::vector<>。以下代码是我到目前为止所实现的:

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

namespace boost { namespace property_tree
{

template<typename type>
struct vector_xml_translator
{
    boost::optional<std::vector<type> > get_value(const std::string& str)
    {
        if (!str.empty())
        {
            std::vector<type> values;
            std::stringstream ss(str);

            while (ss)
            {
                type temp_value;
                ss >> temp_value;
                values.push_back(temp_value);
            }

            return boost::optional<std::vector<type> >(values);
        }
        else
        {
            return boost::optional<std::vector<type> >(boost::none);
        }
    }

    boost::optional<std::string> put_value(const std::vector<type>& b)
    {
        std::stringstream ss;
        for (unsigned int i = 0; i < b.size(); i++)
        {
            ss << b[i];
            if (i != b.size()-1)
            {
                ss << " ";
            }
        }
        return boost::optional<std::string>(ss.str());
    }
};

template<typename ch, typename traits, typename alloc, typename data_type>
struct translator_between<std::basic_string<ch, traits, alloc>, std::vector<data_type> >
{
    typedef vector_xml_translator<data_type> type;
};

} // namespace property_tree
} // namespace boost

测试此代码的最小示例如下:

#include <fstream>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <XML_Vector_Translator.hpp>


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

    std::vector<double> test_vector;

    test_vector.push_back(1);
    test_vector.push_back(6);
    test_vector.push_back(3);


    ptree pt;
    pt.add("base", test_vector);

    std::ofstream os("test_file.xml");

    write_xml(os, pt, boost::property_tree::xml_writer_settings<std::string>(' ', 2));

    std::ifstream is("test_file.xml");

    ptree pt_2;
    read_xml(is, pt_2);

    std::vector<int> test_vector_2;

    test_vector_2 = pt_2.get<std::vector<int> >("base");

    for (unsigned int i = 0; i < test_vector_2.size(); i++)
    {
        std::cout << test_vector_2[i] << std::endl;
    }

    return 0;
}

当我运行这段代码时,我收到了许多错误,这使我相信翻译器结构的注册不正确。有人知道如何解决这个问题和/或改进这个代码吗?


  1. 正如较旧的答案also指出您必须满足以下要求boost::property_tree::detail::is_translator,所以你需要internal_type / external_type类型定义。

    typedef T internal_type;
    typedef T external_type;
    
  2. 接下来,循环错误,需要检查值提取的结果:

    while (ss >> temp_value)
        values.push_back(temp_value);
    
  3. 将您自己的类型放入 boost 命名空间中是不好的做法。只有专业化translator_between<>需要在那里。

  4. 您可以简化和概括很多代码

全部在一个工作演示中:

Live On Coliru http://coliru.stacked-crooked.com/a/2d31028ff991d28b

#include <boost/optional.hpp>
#include <boost/property_tree/ptree.hpp>
#include <vector>
#include <list>

namespace mylib { namespace xml_translators {

    template<typename T> struct container
    {
        // types
        typedef T internal_type;
        typedef T external_type;

        boost::optional<T> get_value(const std::string& str) const
        {
            if (str.empty())
                return boost::none;

            T values;
            std::stringstream ss(str);

            typename T::value_type temp_value;
            while (ss >> temp_value)
                values.insert(values.end(), temp_value);

            return boost::make_optional(values);
        }

        boost::optional<std::string> put_value(const T& b) {
            std::stringstream ss;
            size_t i = 0;
            for (auto v : b)
                ss << (i++?" ":"") << v;
            return ss.str();
        }
    };

} }

namespace boost { namespace property_tree {
    template<typename ch, typename traits, typename alloc, typename T>
        struct translator_between<std::basic_string<ch, traits, alloc>, std::vector<T> > {
            typedef mylib::xml_translators::container<std::vector<T> > type;
        };

    template<typename ch, typename traits, typename alloc, typename T>
        struct translator_between<std::basic_string<ch, traits, alloc>, std::list<T> > {
            typedef mylib::xml_translators::container<std::list<T> > type;
        };
} }

#include <sstream>
#include <iostream>
#include <boost/property_tree/xml_parser.hpp>

int main()
{
    std::stringstream ss;
    using boost::property_tree::ptree;

    {
        ptree pt;
        pt.add("base", std::vector<double> { 1, 6, 3 });

        write_xml(ss, pt, boost::property_tree::xml_writer_settings<std::string>(' ', 2));
    }

    {
        ptree pt;
        read_xml(ss, pt);

        std::cout << "As string: '" << pt.get("base", "") << "'\n";
        auto roundtrip = pt.get<std::list<int> >("base");
        for (auto i : roundtrip)
            std::cout << i << std::endl;
    }
}

Prints

As string: '1 6 3'
1
6
3

¹ Boost property_tree:每个键有多个值 https://stackoverflow.com/questions/13072704/boost-property-tree-multiple-values-per-key,另请参阅恒等转换器http://www.boost.org/doc/libs/1_64_0/doc/html/boost/property_tree/id_translator.html http://www.boost.org/doc/libs/1_64_0/doc/html/boost/property_tree/id_translator.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Boost::property_tree:在 XML 解析器中使用 std::vector<> 在一个键中存储多个值 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 用于 FTP 的文件系统观察器

    我怎样才能实现FileSystemWatcherFTP 位置 在 C 中 这个想法是 每当 FTP 位置添加任何内容时 我都希望将其复制到我的本地计算机 任何想法都会有所帮助 这是我之前问题的后续使用 NET 进行选择性 FTP 下载 ht
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐