| 913 | G.add_edge(target, source, key=edge_id, **data) |
| 914 | |
| 915 | def decode_attr_elements(self, gexf_keys, obj_xml): |
| 916 | # Use the key information to decode the attr XML |
| 917 | attr = {} |
| 918 | # look for outer '<attvalues>' element |
| 919 | attr_element = obj_xml.find(f"{{{self.NS_GEXF}}}attvalues") |
| 920 | if attr_element is not None: |
| 921 | # loop over <attvalue> elements |
| 922 | for a in attr_element.findall(f"{{{self.NS_GEXF}}}attvalue"): |
| 923 | key = a.get("for") # for is required |
| 924 | try: # should be in our gexf_keys dictionary |
| 925 | title = gexf_keys[key]["title"] |
| 926 | except KeyError as err: |
| 927 | raise eg.EasyGraphError(f"No attribute defined for={key}.") from err |
| 928 | atype = gexf_keys[key]["type"] |
| 929 | value = a.get("value") |
| 930 | if atype == "boolean": |
| 931 | value = self.convert_bool[value] |
| 932 | else: |
| 933 | value = self.python_type[atype](value) |
| 934 | if gexf_keys[key]["mode"] == "dynamic": |
| 935 | # for dynamic graphs use list of three-tuples |
| 936 | # [(value1,start1,end1), (value2,start2,end2), etc] |
| 937 | ttype = self.timeformat |
| 938 | start = self.python_type[ttype](a.get("start")) |
| 939 | end = self.python_type[ttype](a.get("end")) |
| 940 | if title in attr: |
| 941 | attr[title].append((value, start, end)) |
| 942 | else: |
| 943 | attr[title] = [(value, start, end)] |
| 944 | else: |
| 945 | # for static graphs just assign the value |
| 946 | attr[title] = value |
| 947 | return attr |
| 948 | |
| 949 | def find_gexf_attributes(self, attributes_element): |
| 950 | # Extract all the attributes and defaults |