Boost Read_graphml没有正确读取xml它给出了所有顶点但它们都是空的

问题描述 投票:1回答:1

我有一个类型的邻接列表

boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData>

其中GraphData是一个包含名称的结构

struct GraphItem
{
    std::string Name;
}

我能够将图形写入xml

void WriteGraph() {
     boost::dynamic_properties dp;

     dp.property("Name", make_transform_value_property_map(&Name, 
     boost::get(vertex_bundle, graph)));

     boost::write_graphml(filename, graph, dp, true); 
}

std::string Name(boost::vertex_bundle_type<Graph>::type v) {
    std::ostringstream oss;
    oss << v.Name;
    return oss.str();
}

我把XML作为

<graphml>
  <key id="key0" for="node" attr.name="Name" attr.type="string" />
  <graph id="G" edgedefault="directed" parse.nodeids="canonical" 
   parse.edgeids="canonical" parse.order="nodesfirst">
    <node id="n0">
      <data key="key0">A</data>
    </node>
    <node id="n1">
      <data key="key0">D</data>
    </node>
    <node id="n2">
      <data key="key0">B</data>
    </node>
    <node id="n3">
      <data key="key0">C</data>
    </node>
    <edge id="e0" source="n0" target="n1">
    </edge>
    <edge id="e1" source="n2" target="n3">
    </edge>
  </graph>
</graphml>

当我读图

void ReadGraph() {
    boost::dynamic_properties dp;
    std::ifstream file(fileName);
    boost::read_graphml(file, graph, dp);
}

这是崩溃说找不到属性名称。如果我使用ignore_other_properties属性,

boost::dynamic_properties dp(ignore_other_properties);

它可以工作,但我没有得到图顶点的任何图形项。

c++ boost boost-graph graphml
1个回答
1
投票

图表不为空,您得到:

0 --> 1 
1 --> 
2 --> 3 
3 --> 

或者用XML:https://paste.ubuntu.com/p/c4tGmxGssJ/

当然,您想要读取name属性。为此,您显然需要使用动态属性映射注册该属性。

注意您可以更简单地访问属性包的成员:

    dp.property("Name", boost::get(&GraphData::Name, graph));

完整的演示

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphml.hpp>

struct GraphData {
    std::string Name;
};

using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, GraphData>;

Graph ReadGraph(std::string const& fileName) {
    Graph graph;
    boost::dynamic_properties dp;
    dp.property("Name", boost::get(&GraphData::Name, graph));

    std::ifstream file(fileName);
    boost::read_graphml(file, graph, dp);

    return graph;
}

void WriteGraph(std::ostream& os, Graph& graph) {
    boost::dynamic_properties dp;
    dp.property("Name", get(&GraphData::Name, graph));

    boost::write_graphml(os, graph, dp, true); 
}

#include <boost/graph/graph_utility.hpp>

int main() {
    Graph g = ReadGraph("input.txt");
    print_graph(g, get(&GraphData::Name, g));

    // or as XML
    WriteGraph(std::cout << "==== XML version: ====\n\n", g);
}

打印

A --> D 
D --> 
B --> C 
C --> 
==== XML version: ====

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
  <key id="key0" for="node" attr.name="Name" attr.type="string" />
  <graph id="G" edgedefault="directed" parse.nodeids="canonical" parse.edgeids="canonical" parse.order="nodesfirst">
    <node id="n0">
      <data key="key0">A</data>
    </node>
    <node id="n1">
      <data key="key0">D</data>
    </node>
    <node id="n2">
      <data key="key0">B</data>
    </node>
    <node id="n3">
      <data key="key0">C</data>
    </node>
    <edge id="e0" source="n0" target="n1">
    </edge>
    <edge id="e1" source="n2" target="n3">
    </edge>
  </graph>
</graphml>
© www.soinside.com 2019 - 2024. All rights reserved.