- Home /
The question is answered, right answer was accepted
System.Xml.XmlException: Root element is missing
I am serializing a ScriptableObject serialization goes fine but when trying to deserialize back to SO I get an ecxeption error saying the root element is missing where as you can see the output is a valid XML document. The code below is used for serialization:
static void SerializeSO(SO_LevelObjects dser)
{
Encoding LocalEncoding = Encoding.UTF8;
MemoryStream fs = new MemoryStream();
TextWriter Rtext = new StreamWriter(fs, LocalEncoding);
//removes xsi and xsd attributes from root element
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer so2xml = new XmlSerializer(typeof(SO_LevelObjects));
so2xml.Serialize(Rtext, dser,ns);
try
{
dser = (SO_LevelObjects)so2xml.Deserialize(fs);
}
catch (Exception e)
{
//reading content of fs (MemoryStream) to check content see output below
Debug.Log(LocalEncoding.GetString(fs.ToArray()));
Debug.Log(e.InnerException);
Debug.Log(e.Message);
Debug.Log(e.TargetSite);
}
fs.Close();
Rtext.Close();
}
Here is the output of Debug.Log(LocalEncoding.GetString(fs.ToArray()));
<?xml version="1.0" encoding="utf-8"?>
<SO_LevelObjects>
<name>so_Obstacles</name>
<hideFlags>None</hideFlags>
<lst_Obstacle>
<Obstacles>
<Obs_Name>test1</Obs_Name>
<obstacle>objTest1</obstacle>
</Obstacles>
<Obstacles>
<Obs_Name>test2</Obs_Name>
<obstacle>objTest2</obstacle>
</Obstacles>
<Obstacles>
<Obs_Name>test3</Obs_Name>
<obstacle>objTest3</obstacle>
</Obstacles>
<Obstacles>
<Obs_Name>test4</Obs_Name>
<obstacle>objTest4</obstacle>
</Obstacles>
<Obstacles>
<Obs_Name>test5</Obs_Name>
<obstacle>objTest5</obstacle>
</Obstacles>
</lst_Obstacle>
</SO_LevelObjects>
Answer by Bunny83 · Aug 24, 2020 at 02:15 PM
I see several potential issues here. First of all a common issue is if you load the XML data from a file, that the file is saved with a byte order mark (BOM) which the XmlSerializer can't process properly. See this question for more details.
However in your case the issue might be more trivial. You use a MemoryStream to write to / read from . Though you have not reset the position after writing. So reading from the same memory stream would read from the current position which is the end of the stream.
You should do:
// [ ... ]
so2xml.Serialize(Rtext, dser,ns);
fs.Position = 0;
// [ ... ]
Also be careful with the StreamWriter. It actually "owns" the stream it's writing to. So closing the writer would close the MemoryStream as well. For more information, see this SO question
@Bunny83 indeed It was the cursor position that had to be reset :p I was using fs.Read() before and setting position to zero as a param. It works find now just that warning regarding using ScriptableObject.CreateInstance I don't see myself overriding the hole deserialization class to use it instead of new class() instruction. Thank you very much.
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
XMLSerializer 0 Answers
Deserialize (stream) wants CreateInstance method 0 Answers
Multiple Cars not working 1 Answer
Deserializing problem at runtime, InvalidCastException 1 Answer