c++ - 使用 Boost 解析 XML 属性

标签 c++ xml boost boost-propertytree

我想与您分享一个我在尝试使用 Boost 库(版本 1.52.0)处理 C++ 中 XML 元素的某些属性时遇到的问题。给定以下代码:

#define ATTR_SET ".<xmlattr>"
#define XML_PATH1 "./pets.xml"

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

using namespace std;
using namespace boost;
using namespace boost::property_tree;

const ptree& empty_ptree(){
    static ptree t;
    return t;
}

int main() {
    ptree tree;
    read_xml(XML_PATH1, tree);
    const ptree & formats = tree.get_child("pets", empty_ptree());
    BOOST_FOREACH(const ptree::value_type & f, formats){
        string at = f.first + ATTR_SET;
        const ptree & attributes = formats.get_child(at, empty_ptree());
        cout << "Extracting attributes from " << at << ":" << endl;
        BOOST_FOREACH(const ptree::value_type &v, attributes){
            cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl;
        }
    }
}

假设我有以下 XML 结构:

<?xml version="1.0" encoding="utf-8"?>
<pets>
    <cat name="Garfield" weight="4Kg">
        <somestuff/>
    </cat>
    <dog name="Milu" weight="7Kg">
        <somestuff/>
    </dog>
    <bird name="Tweety" weight="0.1Kg">
        <somestuff/>
    </bird>
</pets>

因此,我将得到的控制台输出将是下一个:

Extracting attributes from cat.<xmlattr>:
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from dog.<xmlattr>:
First: name Second: Milu
First: weight Second: 7Kg
Extracting attributes from bird.<xmlattr>:
First: name Second: Tweety
First: weight Second: 0.1Kg

但是,如果我决定为从根节点开始放置的每个元素使用一个通用结构(以便从它们的特定属性中识别它们),结果将完全改变。在这种情况下,这可能是 XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<pets>
    <pet type="cat" name="Garfield" weight="4Kg">
        <somestuff/>
    </pet>
    <pet type="dog" name="Milu" weight="7Kg">
        <somestuff/>
    </pet>
    <pet type="bird" name="Tweety" weight="0.1Kg">
        <somestuff/>
    </pet>
</pets>

输出如下:

Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg
Extracting attributes from pet.<xmlattr>:
First: type Second: cat
First: name Second: Garfield
First: weight Second: 4Kg

似乎可以正确识别卡在根节点上的元素数量,因为已经打印了三组属性。尽管如此,它们都引用了第一个元素的属性...

我不是 C++ 专家,而且对 Boost 很陌生,所以这可能是我在 HashMap 处理方面缺少的东西......任何建议都将不胜感激。

最佳答案

你程序的问题出在这一行:

const ptree & attributes = formats.get_child(at, empty_ptree());

通过这一行,您要求得到 child pet.<xmlattr>来自 pets并且您独立于 f 执行此操作 3 次你正在穿越。关注 this article我猜你需要使用的是:

const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree());

适用于您的两个 xml 文件的完整代码是:

#define ATTR_SET ".<xmlattr>"
#define XML_PATH1 "./pets.xml"

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

using namespace std;
using namespace boost;
using namespace boost::property_tree;

const ptree& empty_ptree(){
    static ptree t;
    return t;
}

int main() {
    ptree tree;
    read_xml(XML_PATH1, tree);
    const ptree & formats = tree.get_child("pets", empty_ptree());
    BOOST_FOREACH(const ptree::value_type & f, formats){
        string at = f.first + ATTR_SET;
        const ptree & attributes = f.second.get_child("<xmlattr>", empty_ptree());
        cout << "Extracting attributes from " << at << ":" << endl;
        BOOST_FOREACH(const ptree::value_type &v, attributes){
            cout << "First: " << v.first.data() << " Second: " << v.second.data() << endl;
        }
    }
}

关于c++ - 使用 Boost 解析 XML 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14010473/

相关文章:

c++ - 如何在 Linux 中使用 C++ 下载受密码保护的 URL?

c++ - 正确编写基于范围的构造函数

php - 按原样显示 XML 信息

java - 使用 Jackson 解析 XML 时出现 MismatchedInputException

c++ - 如何线程化作为类方法的可调用函数

boost - 使用 VS2012 RC 构建 boost

c++ - 无法包含来自 boost 库的 header

c++ - "Error: Redefinition of Class"- 但没有重新声明

c++ - 为什么此代码无法读取 Blender 的 .obj 文件?

android - 在 Android 中,单击其他所有内容时是否展开布局?