JSON does not natively support graph storage. There are some formats, such as JGF JSON Graph Format, to provide a common encoding.
The following is a JGF graph encoded in JSON.
{
"nodes": [
{
"id": "0",
"metadata": {
"member0": 44,
"member1": "value1",
"member2": true
}
},
{
"id": "1",
"metadata": {
"member0": 2323,
"member1": "value4",
"member2": false
}
},
{
"id": "2",
"metadata": {
"member0": 1234,
"member1": "value7",
"member2": false
}
}
],
"edges": [
{
"source": "0",
"target": "1"
},
{
"source": "1",
"target": "0"
},
{
"source": "2",
"target": "0"
},
{
"source": "1",
"target": "2"
}
]
}
The code below uses a json_array_range
to iterate over the nodes and edges separately to populate the internal graph. The "id"
members are an example of parsing strings as numbers with the LiteralAsString
option. The JSON document does not directly represent the in memory representation. To see a working example using this code, refer to cookbook_graphs1_test.cpp
++
struct Metadata {
int member0;
std::string member1;
bool member2;
};
struct GraphNode {
size_t id;
Metadata metadata;
};
struct GraphEdge {
size_t source;
size_t target;
};
template<>
struct json_data_contract<Metadata> {
using type = json_member_list<
json_number<"member0", int>,
json_string<"member1">,
json_bool<"member2">>;
};
template<>
struct json_data_contract<GraphNode> {
using type = json_member_list<
json_number<"id", size_t, LiteralAsStringOpt::Always>,
json_class<"metadata", Metadata>>;
};
template<>
struct json_data_contract<GraphEdge> {
using type = json_member_list<
json_number<"source", size_t, LiteralAsStringOpt::Always>,
json_number<"target", size_t, LiteralAsStringOpt::Always>>;
};
}
struct Node {
size_t id;
int member0;
std::string member1;
bool member2;
};
std::string_view json_sv = load_json_data( );
daw::graph_t<Node> g{};
for( auto node : node_range_t( json_sv, "nodes" ) ) {
g.add_node( node.id, node.metadata.member0, node.metadata.member1,
node.metadata.member2 );
}
auto const find_node_id = [&g]( size_t id ) -> std::optional<daw::node_id_t> {
auto result =
g.find( [id]( auto const &node ) { return node.value( ).id == id; } );
if( result.empty( ) ) {
return {};
}
return result.front( );
};
for( auto edge : edge_range_t( json_sv, "edges" ) ) {
auto source_id = *find_node_id( edge.source );
auto target_id = *find_node_id( edge.target );
g.add_directed_edge( source_id, target_id );
}
Customization point traits.
missing_json_data_contract_for_or_unknown_type< T > type
A range of json_array_iterators.