c++ - Boost 和 xml 解析

标签 c++ xml boost

我有以下 xml 数据,我想通过 boost xml 解析器进行解析。

<?xml version="1.0" encoding="UTF-8"?>
<applications>
    <application>
            <id>1</id>
            <platform>linux-x64</platform>
            <version>2.4</version>
    </application>
    <application>
            <id>2</id>
            <platform>windows</platform>
            <version>2.5</version>
    </application>
    <application>
            <id>3</id>
            <platform>linux</platform>
            <version>2.6</version>
    </application>
</applications>

我已经编写了下面的 boost 代码,但我只读取了“应用程序”的第一个子级,而无法读取其他两个子级。每次内循环都会获取第一个子级的数据。

boost::property_tree::ptree pt;
boost::property_tree::read_xml(sModel, pt); // sModel is filename which contains above xml data

BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("applications"))
{
    std::string key = v.first.data();       
    std::string Id, platform, version;

    if (key == std::string("application"))
    {
        BOOST_FOREACH(boost::property_tree::ptree::value_type &v_, pt.get_child("applications.application"))
        {
            std::string app_key = v_.first.data();
            std::string app_value = v_.second.data();

            if (app_key == std::string("id"))
                pkgId = app_value;
            else if (app_key == std::string("platform"))
                platform = app_value;
            else if (app_key == std::string("version"))
                version = app_value;
        }
    }
}

在这里,每次我得到的平台都是“linux-x64”。 有人可以指导如何通过这个 boost xml 读取所有子项吗?

提前致谢。

最佳答案

get_child (以及所有其他基于路径的访问函数)不太擅长处理多个相同的键。它将选择具有给定键的第一个子级并将其返回,忽略所有其他子级。

但你不需要get_child ,因为你手里已经拿着你想要的节点了。

pt.get_child("applications")给你一个ptree 。迭代得到 ptree::value_type ,这是 std::pair<std::string, ptree> .

第一个奇怪的事情就是这一行:

std::string key = v.first.data();

data()您在这里调用的函数是 std::string::data ,不是ptree::data 。你可以直接写

std::string key = v.first;

下一个奇怪的事情是比较:

if (key == std::string("application"))

您不需要显式构造 std::string这里。事实上,这样做是一种悲观的做法,因为它必须分配一个字符串缓冲区并将字符串复制到那里,当std::string时。具有 C 风格字符串的比较运算符。

然后你迭代pt.get_child("applications.application") ,但您不需要执行此查找 - v.second已经是你想要的树了。

此外,您根本不需要迭代子级,您可以使用它的查找函数来获取您需要的内容。

std::string pkgId = v.second.get("id", "");

总而言之,这是我要编写的代码:

boost::property_tree::ptree pt;
boost::property_tree::read_xml(sModel, pt);

BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("applications"))
{
    // You can even omit this check if you can rely on all children
    // being application nodes.
    if (v.first == "application")
    {
        std::string pkgId = v.second.get("id", "");
        std::string platform = v.second.get("platform", "");
        std::string version = v.second.get("version", "");
    }
}

关于c++ - Boost 和 xml 解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47568808/

相关文章:

ubuntu - 如何从 CMake 访问 Boost on Boost 1.66 和 1.67

c++ - boost 序列化 binary_oarchive 崩溃

c++ - 删除时的二维数组访问冲突(Borland C++)

c++ - 访问我只想存在于派生类中的函数

xml - Hive XML Serde-解析带换行符的字符串

java - 是否有一个 java API 可以生成带有内联模式定义的 xml

java - C++中接口(interface)的匿名实现

c++ -++x %= 10 在 C++ 中是否明确定义?

python - libxml 解决 python 的 utf 编码问题还是我的问题?

c++ - Boost.Log 和创建守护进程; `fork` 不允许?