I am trying to use the read_graphml
function from the Boost library to read some .graphml files in a C++ application that I am developing. However, I am running into unexpected difficulties in reading properties. Here is a MWE of my code:
#include <iostream>
#include <fstream>
#include <boost/graph/graphml.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
using namespace boost;
int main(int, char**){
typedef adjacency_list<vecS, setS, undirectedS> Graph;
std::ifstream graph_file;
graph_file.open("more_exampleHoles_8.graphml", std::ifstream::in);
Graph g;
boost::dynamic_properties dp;
boost::read_graphml(graph_file, g, dp);
}
Here is the contents of more_exampleHoles_8.graphml
:
<?xml version='1.0' encoding='UTF-8'?>
<!-- created by IGraph/M, http://szhorvat.net/mathematica/IGraphM -->
<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="v_betti"
for="node"
attr.name="betti"
attr.type="long" />
<key for='node'
id='v_dimk'
attr.name='dimk'
attr.type='long' />
<key for='node'
id='v_gap'
attr.name='gap'
attr.type='double' />
<graph id='Graph'
edgedefault='undirected'>
<node id="1">
<data key="v_betti">5</data>
<data key='v_dimk'>1</data>
<data key='v_gap'>0.12405641442417092</data>
</node>
<node id='2' />
<node id='3' />
<node id='4' />
<node id='5' />
<node id='6' />
<node id='7' />
<node id='8' />
<node id='9' />
<node id='10' />
<node id='11' />
<node id='12' />
<edge source='1'
target='2' />
<edge source='1'
target='3' />
<edge source='1'
target='4' />
<edge source='1'
target='8' />
<edge source='2'
target='7' />
<edge source='2'
target='9' />
<edge source='2'
target='11' />
<edge source='3'
target='5' />
<edge source='3'
target='10' />
<edge source='4'
target='5' />
<edge source='4'
target='6' />
<edge source='4'
target='7' />
<edge source='4'
target='8' />
<edge source='4'
target='9' />
<edge source='4'
target='11' />
<edge source='5'
target='9' />
<edge source='5'
target='10' />
<edge source='6'
target='8' />
<edge source='7'
target='10' />
<edge source='8'
target='10' />
<edge source='9'
target='11' />
</graph>
</graphml>
When running the code, I receive the following output:
terminate called after throwing an instance of 'boost::wrapexcept<boost::property_not_found>'
what(): Property not found: betti.
Aborted (core dumped)
I am pretty confident that the graphml is well formed, so this seems to me to be a bug with the read_graphml function. If I remove the following lines from the .graphml file, everything works fine, but of course I don't want to remove these lines.
<data key="v_betti">5</data>
<data key='v_dimk'>1</data>
<data key='v_gap'>0.12405641442417092</data>
Boost expects you to define property maps for all properties present. If you want to ignore unknown properties, add the filter to the dynamic properties constructor:
boost::dynamic_properties dp(boost::ignore_other_properties);
Alternatively, add the property maps:
#include <boost/graph/graphml.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <fstream>
#include <iostream>
struct VertexProps {
long betti, dimk;
double gap;
};
using Graph = boost::adjacency_list<boost::vecS, boost::setS, boost::undirectedS, VertexProps>;
int main() {
std::ifstream graph_file("more_exampleHoles_8.graphml");
Graph g;
boost::dynamic_properties dp;
dp.property("betti", get(&VertexProps::betti, g));
dp.property("dimk", get(&VertexProps::dimk, g));
dp.property("gap", get(&VertexProps::gap, g));
read_graphml(graph_file, g, dp);
}