Read a GraphML document. Produces EasyGraph graph objects.
| 840 | |
| 841 | |
| 842 | class GraphMLReader(GraphML): |
| 843 | """Read a GraphML document. Produces EasyGraph graph objects.""" |
| 844 | |
| 845 | def __init__(self, node_type=str, edge_key_type=int, force_multigraph=False): |
| 846 | self.construct_types() |
| 847 | self.node_type = node_type |
| 848 | self.edge_key_type = edge_key_type |
| 849 | self.multigraph = force_multigraph # If False, test for multiedges |
| 850 | self.edge_ids = {} # dict mapping (u,v) tuples to edge id attributes |
| 851 | |
| 852 | def __call__(self, path=None, string=None): |
| 853 | from xml.etree.ElementTree import ElementTree |
| 854 | from xml.etree.ElementTree import fromstring |
| 855 | |
| 856 | if path is not None: |
| 857 | self.xml = ElementTree(file=path) |
| 858 | elif string is not None: |
| 859 | self.xml = fromstring(string) |
| 860 | else: |
| 861 | raise ValueError("Must specify either 'path' or 'string' as kwarg") |
| 862 | (keys, defaults) = self.find_graphml_keys(self.xml) |
| 863 | for g in self.xml.findall(f"{{{self.NS_GRAPHML}}}graph"): |
| 864 | yield self.make_graph(g, keys, defaults) |
| 865 | |
| 866 | def make_graph(self, graph_xml, graphml_keys, defaults, G=None): |
| 867 | # set default graph type |
| 868 | edgedefault = graph_xml.get("edgedefault", None) |
| 869 | if G is None: |
| 870 | if edgedefault == "directed": |
| 871 | G = eg.MultiDiGraph() |
| 872 | else: |
| 873 | G = eg.MultiGraph() |
| 874 | # set defaults for graph attributes |
| 875 | G.graph["node_default"] = {} |
| 876 | G.graph["edge_default"] = {} |
| 877 | for key_id, value in defaults.items(): |
| 878 | key_for = graphml_keys[key_id]["for"] |
| 879 | name = graphml_keys[key_id]["name"] |
| 880 | python_type = graphml_keys[key_id]["type"] |
| 881 | if key_for == "node": |
| 882 | G.graph["node_default"].update({name: python_type(value)}) |
| 883 | if key_for == "edge": |
| 884 | G.graph["edge_default"].update({name: python_type(value)}) |
| 885 | # hyperedges are not supported |
| 886 | hyperedge = graph_xml.find(f"{{{self.NS_GRAPHML}}}hyperedge") |
| 887 | if hyperedge is not None: |
| 888 | raise eg.EasyGraphError("GraphML reader doesn't support hyperedges") |
| 889 | # add nodes |
| 890 | for node_xml in graph_xml.findall(f"{{{self.NS_GRAPHML}}}node"): |
| 891 | self.add_node(G, node_xml, graphml_keys, defaults) |
| 892 | # add edges |
| 893 | for edge_xml in graph_xml.findall(f"{{{self.NS_GRAPHML}}}edge"): |
| 894 | self.add_edge(G, edge_xml, graphml_keys) |
| 895 | # add graph data |
| 896 | data = self.decode_data_elements(graphml_keys, graph_xml) |
| 897 | G.graph.update(data) |
| 898 | |
| 899 | # switch to Graph or DiGraph if no parallel edges were found |
no outgoing calls
no test coverage detected