code: def get_attr_id(self, title, attr_type, edge_or_node, default, mode):
      # find the id of the attribute or generate a new id
      try:
          return self.attr[edge_or_node][mode][title]
      except KeyError:
          # generate new id
          new_id = str(next(self.attr_id))
          self.attr[edge_or_node][mode][title] = new_id
          attr_kwargs = {
              "id": new_id,
              "title": title,
              "type": attr_type,
          }
          attribute = Element("attribute", **attr_kwargs)
          # add subelement for data default value if present
          default_title = default.get(title)
          if default_title is not None:
              default_element = Element("default")
              default_element.text = str(default_title)
              attribute.append(default_element)
          # new insert it into the XML
          attributes_element = None
          for a in self.graph_element.findall("attributes"):
              # find existing attributes element by class and mode
              a_class = a.get("class")
              a_mode = a.get("mode", "static")
              if a_class == edge_or_node and a_mode == mode:
                  attributes_element = a
          if attributes_element is None:
              # create new attributes element
              attr_kwargs = {"mode": mode, "class": edge_or_node}
              attributes_element = Element("attributes", **attr_kwargs)
              self.graph_element.insert(0, attributes_element)
          attributes_element.append(attribute)
      return new_id
  
imports: import itertools
  import time
  from xml.etree.ElementTree import Element, ElementTree, SubElement, register_namespace, tostring
  import networkx
  from networkx.utils import open_file
label_desc: Use image node_id 7 for calling the GEXFWriter obj's underlying member method code with example usage: obj.get_attr_id(title, attr_type, edge_or_node, default, mode) and returns: new_id, self