docs: def xmlSpectrumFromSmi(index, smi, sai=None, compression='zlib'):
      """ #TODO: docstring
  
      :param index: The zero-based, consecutive index of the spectrum in the
          SpectrumList. (mzML specification)
      :param smi: a SpectrumMetadataItem instance
      :param sai: a SpectrumArrayItem instance, if none is specified no
          binaryDataArrayList is written
      :param compression: #TODO: docstring
  
      :returns: #TODO: docstring
      """
      if sai is not None:
          arrayLength = [array.size for array in viewvalues(sai.arrays)]
          if len(set(arrayLength)) != 1:
              raise Exception('Unequal size for different array in sai.arrays')
          else:
              arrayLength = arrayLength[0]
      else:
          arrayLength = 0
  
      spectrumAttrib = {'index': str(index), 'id': smi.attributes['id'],
                        'defaultArrayLength': str(arrayLength)}
  
      xmlSpectrum = ETREE.Element('spectrum', **spectrumAttrib)
      maspy.xml.xmlAddParams(xmlSpectrum, smi.params)
      #Add the scanList
      if len(smi.scanList) > 0:
          xmlSpectrum.append(xmlGenScanList(smi.scanList, smi.scanListParams))
      if len(smi.precursorList) > 0:
          xmlSpectrum.append(xmlGenPrecursorList(smi.precursorList))
      if len(smi.productList) > 0:
          xmlSpectrum.append(xmlGenProductList(smi.productList))
      if sai is not None:
          xmlSpectrum.append(xmlGenBinaryDataArrayList(sai.arrayInfo,
                                                       sai.arrays,
                                                       compression=compression
                                                       ))
      return xmlSpectrum