Ok, here is a very simple and practical example of the difference…
I have two classes:
    [Serializable()]
    public class HighScoreEntry
    {
        public DateTime DateAchieved = DateTime.UtcNow;
        public int Level = 0;
        public int Difficulty = 0;
        public long Score = 0;
        public int Rank = 0;
        public string Initials = "";
        //TODO: Add Game Stats object
        public HighScoreEntry()
        {
        }
    }
and then just a simple collection:
	public class HighScoreCollection : List<HighScoreEntry>
	{
	}
So Serialize the Collection in XML I use:
        /// <summary>
        /// Returns a string of XML that represents the object passed in.
        /// </summary>
        /// <param name="p_object">The object to serialize.</param>
        /// <returns>XML string representing object</returns>
        /// <remarks></remarks>
        public static string XMLSerialize(object p_object)
        {
            System.IO.MemoryStream tempMemStream = new System.IO.MemoryStream();
            System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings();
            string tempString;
            settings.Indent = true;
            settings.Encoding = System.Text.Encoding.UTF8;
            settings.NewLineChars = System.Environment.NewLine;
            settings.NewLineHandling = System.Xml.NewLineHandling.Replace;
            using (System.IO.StringWriter stringWriter = new System.IO.StringWriter())
            {
                using (System.Xml.XmlWriter xmlWriter = System.Xml.XmlWriter.Create(stringWriter, settings))
                {
                    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(p_object.GetType());
                    serializer.Serialize(xmlWriter, p_object);
                    tempString = stringWriter.ToString();
                    xmlWriter.Close();
                }
                stringWriter.Close();
            }
            return tempString;
        }
and I get the output of
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfHighScoreEntry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>19800000</Score>
    <Rank>1</Rank>
    <Initials>AAA</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>18000</Score>
    <Rank>2</Rank>
    <Initials>BBB</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>17000</Score>
    <Rank>3</Rank>
    <Initials>CCC</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>16000</Score>
    <Rank>4</Rank>
    <Initials>DDD</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>15000</Score>
    <Rank>5</Rank>
    <Initials>EEE</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>14000</Score>
    <Rank>6</Rank>
    <Initials>FFF</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>13000</Score>
    <Rank>7</Rank>
    <Initials>GGG</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>12000</Score>
    <Rank>8</Rank>
    <Initials>HHH</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>11000</Score>
    <Rank>9</Rank>
    <Initials>III</Initials>
  </HighScoreEntry>
  <HighScoreEntry>
    <DateAchieved>2020-12-29T03:21:15.4197663Z</DateAchieved>
    <Level>0</Level>
    <Difficulty>0</Difficulty>
    <Score>10000</Score>
    <Rank>10</Rank>
    <Initials>JJJ</Initials>
  </HighScoreEntry>
</ArrayOfHighScoreEntry>
The JSON serialization is a little trickier as it uses a Contract Resolver…(at least in my case).
This allows me to include or exclude properties as I need.  99% of the time, I just serialize everything.
    public class JsonContractResolver : DefaultContractResolver
    {
        System.Collections.Generic.List<string> m_excludePropertyNames = null;
        System.Collections.Generic.List<string> m_includePropertyNames = null;
        public JsonContractResolver(System.Collections.Generic.List<string> p_excludePropertyNames, System.Collections.Generic.List<string> p_includePropertyNames)
        {
            m_excludePropertyNames = p_excludePropertyNames;
            m_includePropertyNames = p_includePropertyNames;
        }
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
            string propertyName = "";
            string className = "";
            for (int i = properties.Count - 1; i >= 0; i--)
            {
                propertyName = properties[i].PropertyName;
                switch (propertyName)
                {
                    default:
                        propertyName = properties[i].PropertyName;
                        className = type.FullName;
                        if (m_excludePropertyNames != null)
                        {
                            if (m_excludePropertyNames.Contains(propertyName) || m_excludePropertyNames.Contains(String.Format("{0}.{1}", className, propertyName)))
                            {
                                properties.RemoveAt(i);
                            }
                        }
                        if (m_includePropertyNames != null)
                        {
                            if (!m_includePropertyNames.Contains(propertyName) && !m_includePropertyNames.Contains(String.Format("{0}.{1}", className, propertyName)))
                            {
                                properties.RemoveAt(i);
                            }
                        }
                        break;
                }
            }
            return properties;
        }
    }
Then to serialize the object I use:
        /// <summary>
        /// This takes an object and serializes it using the Newton Json Library.
        /// </summary>
        /// <param name="p_gameObject">The object to serialize</param>
        /// <returns></returns>
        public static string JsonSerialize(object p_gameObject)
        {
            return JsonSerialize(p_gameObject, null, null);
        }
        /// <summary>
        /// This takes an object and serializes it using the Newton Json Library.
        /// </summary>
        /// <param name="p_gameObject">The object to serialize</param>
        /// <param name="p_excludePropertyNames">A list of property names to exclude from the serialization.  You can specify properties on children as well if you fully qualify the property with the full type.</param>
        /// <param name="p_includePropertyNames">A list of property names to include from the serialization.  You can specify properties on children as well if you fully qualify the property with the full type.</param>
        /// <returns></returns>
        public static string JsonSerialize(object p_gameObject, System.Collections.Generic.List<string> p_excludePropertyNames, System.Collections.Generic.List<string> p_includePropertyNames)
        {
            return JsonConvert.SerializeObject(p_gameObject, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new JsonContractResolver(p_excludePropertyNames, p_includePropertyNames) });
        }
I then have code that loads and saves my high scores (This is Windows Centric, so you can modify for different platforms as needed)
       public static string SaveHighScores()
        {
            string jsonData = "";
            string fileName = "";
            try
            {
                jsonData = JsonSerialize(GlobalInfo.HighScores);
                fileName = GetAssetFilename(AssetTypes.Settings, "HighScores.json");
                if (fileName == "")
                {
                    return "Invalid HighScores Filename";
                }
                System.IO.File.WriteAllText(fileName, jsonData);
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
            return string.Empty;
        }
        public static string LoadHighScores()
        {
            string jsonData = "";
            string fileName = "";
            try
            {
                fileName = GetAssetFilename(AssetTypes.Settings, "HighScores.json");
                if (fileName == "")
                {
                    return "Invalid HighScores Filename";
                }
                if (System.IO.File.Exists(fileName))
                {
                    jsonData = System.IO.File.ReadAllText(fileName);
                    GlobalInfo.HighScores = (HighScoreCollection)JsonDeserialize(jsonData, typeof(HighScoreCollection));
                }
                else
                {
                    GlobalInfo.HighScores = new HighScoreCollection();
                    GlobalInfo.HighScores.Add(new HighScoreEntry("AAA", 1, 19800000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("BBB", 2, 18000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("CCC", 3, 17000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("DDD", 4, 16000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("EEE", 5, 15000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("FFF", 6, 14000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("GGG", 7, 13000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("HHH", 8, 12000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("III", 9, 11000, null));
                    GlobalInfo.HighScores.Add(new HighScoreEntry("JJJ", 10, 10000, null));
                    SaveHighScores();
                }
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
            return string.Empty;
        }
 
The GetAssetFilename is just a method I have that returns the path to where I load/save settings, etc…
So when I serialize the collection in JSON I get
[
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 19800000,
    "Rank": 1,
    "Initials": "AAA"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 18000,
    "Rank": 2,
    "Initials": "BBB"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 17000,
    "Rank": 3,
    "Initials": "CCC"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 16000,
    "Rank": 4,
    "Initials": "DDD"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 15000,
    "Rank": 5,
    "Initials": "EEE"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 14000,
    "Rank": 6,
    "Initials": "FFF"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 13000,
    "Rank": 7,
    "Initials": "GGG"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 12000,
    "Rank": 8,
    "Initials": "HHH"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 11000,
    "Rank": 9,
    "Initials": "III"
  },
  {
    "DateAchieved": "2020-12-29T03:21:15.4197663Z",
    "Level": 0,
    "Difficulty": 0,
    "PlayerStats": null,
    "Score": 10000,
    "Rank": 10,
    "Initials": "JJJ"
  }
]
The XML file is 2,533 bytes, the JSON is 1,897 bytes.  The JSON file is 26% smaller in this case.  When the files get very large then the savings really make a difference.