code: def process_nxml(nxml_filename, pmid=None, extra_annotations=None,
                   cleanup=True, add_grounding=True):
      
      if extra_annotations is None:
          extra_annotations = {}
  
      # Create a temporary directory to store the proprocessed input
      pp_dir = tempfile.mkdtemp('indra_isi_pp_output')
  
      pp = IsiPreprocessor(pp_dir)
      extra_annotations = {}
      pp.preprocess_nxml_file(nxml_filename, pmid, extra_annotations)
  
      # Run the ISI reader and extract statements
      ip = process_preprocessed(pp)
      if add_grounding:
          ip.add_grounding()
  
      if cleanup:
          # Remove temporary directory with processed input
          shutil.rmtree(pp_dir)
      else:
          logger.info('Not cleaning up %s' % pp_dir)
  
      return ip
docs: Process an NXML file using the ISI reader
  
      First converts NXML to plain text and preprocesses it, then runs the ISI
      reader, and processes the output to extract INDRA Statements.
  
      Parameters
      ----------
      nxml_filename : str
          nxml file to process
      pmid : Optional[str]
          pmid of this nxml file, to be added to the Evidence object of the
          extracted INDRA statements
      extra_annotations : Optional[dict]
          Additional annotations to add to the Evidence object of all extracted
          INDRA statements. Extra annotations called 'interaction' are ignored
          since this is used by the processor to store the corresponding
          raw ISI output.
      cleanup : Optional[bool]
          If True, the temporary folders created for preprocessed reading input
          and output are removed. Default: True
      add_grounding : Optional[bool]
          If True the extracted Statements' grounding is mapped
  
      Returns
      -------
      ip : indra.sources.isi.processor.IsiProcessor
          A processor containing extracted Statements