docs: def id_and_revision_extractor(self, xml_elt):
          """
          Function for determining an identifier (and, where applicable, timestamp/revision
          information) for extracted embedded content;
          to be used for DINGO's xml-import hook 'id_and_revision_extractor'.
  
          This function is called
  
          - for the top-level node of the XML to be imported.
  
          - for each node at which an embedded object is extracted from the XML
            (when this occurs is governed by the following function, the
            embedding_pred
  
          It must return an identifier and, where applicable, a revision and or timestamp;
          in the form of a dictionary {'id':<identifier>, 'timestamp': <timestamp>}.
          How you format the identifier is up to you, because you will have to adopt
          the code in function xml_import such that the Information Objects
          are created with the proper identifier (consisting of qualifying namespace
          and uri.)
  
          Note: the xml_elt is an XMLNode defined by the Python libxml2 bindings. If you
          have never worked with these, have a look at
  
          - Mike Kneller's brief intro: http://mikekneller.com/kb/python/libxml2python/part1
          - the functions in django-dingos core.xml_utils module
  
          """
          result = {'id': None,
                    'timestamp': None,
          }
  
  
          if xml_elt.properties:
              attributes = extract_attributes(xml_elt, prefix_key_char='@')
              # Extract identifier:
              if '@id' in attributes:
                  result['id'] = attributes['@id']
              elif '@object_reference' in attributes:
                  # 'object_reference' is used as follows::
                  #
                  #     (...)
                  #     <EmailMessageObj:Attachments>
                  #           <EmailMessageObj:File xsi:type="FileObj:FileObjectType"
                  #              object_reference="cybox:object-3cf6a958-5c3f-11e2-a06c-0050569761d3"/>
                  #     </EmailMessageObj:Attachments>
                  #     (...)
                  result['id'] = attributes['@object_reference']
  
              elif '@phase_id' in attributes:
                  result['id'] = attributes['@phase_id']
                  result['extract_empty_embedded'] = True
  
  
              # Unfortunately, STIX/Cybox do not allow for addition of revision/timestamp information
              # along with the identifier of an object. If that does not change, we might start to use
              # a modified version of STIX/CybOX,
              # that allows 'revision_timestamp' information in an attribute whereever an 'id' or 'idref' attribute
              # is allowed.
              # We use a modified version of STIX/CybOX, in which each identifyable object can also carry
              # an attribute 'revision_timestamp'. We cannot use 'timestamp', because there
              # are CybOX elements such as 'Action' that carry a timestamp attribute with a different
              # semantic (the timestamp refers to the action, not the CybOX document)
  
              #if '@revision_timestamp' in attributes:
              #    result['timestamp'] = attributes['@revision_timestamp']
  
          if xml_elt.name == 'STIX_Package':
  
              result['embedding_STIX_Package'] = result['id']
  
              #setContextNode(node)
              #ctxt = xml_elt.xpathNewContext()
              timestamp_text = xml_elt.xpathEval("./*[contains(name(),'STIX_Header')]/*[contains(name(),'Information_Source')]"
                                        "/*[contains(name(),'Time')]/*[contains(name(),'Produced_Time')]/text()") #[id=%s]/Information_Source" % result['id'])
              #ctxt.xpathFreeContext()
  
  
              if timestamp_text:
                  timestamp_string = timestamp_text[0].getContent().strip()
                  naive = parse_datetime(timestamp_string)
                  if naive:
                      # Make sure that information regarding the timezone is
                      # included in the time stamp. If it is not, we chose
                      # utc as default timezone: if we assume that the same
                      # producer of OpenIOC data always uses the same timezone
                      # for filling in the 'last-modified' attribute, then
                      # this serves the main purpose of time stamps for our
                      # means: we can find out the latest revision of a
                      # given piece of data.
                      if not timezone.is_aware(naive):
                          aware = timezone.make_aware(naive,timezone.utc)
                      else:
                          aware = naive
                      result['timestamp']= aware
  
  
  
  
  
          return result