1

I'm trying to load a XML file from the storage like this:

var serializer = new XmlSerializer(typeof(AppModel));
var txt = File.ReadAllText(path);
if (txt.Length > 0)
{
    using (var stringReader = new StringReader(txt))
    {
        var ret = (AppModel)serializer.Deserialize(stringReader);
        return ret;
    }
}

On Windows everything works fine, but on Android an exception is thrown:

System.InvalidOperationException: 'There is an error in XML document (0, 0). Inner Exception: Root element is missing.

But I set my RootElement and as said, this works on Windows, also the string is loaded correctly:

[Serializable]
[XmlRoot("AppModel")]
public class AppModel
{
    //...
}

Am I missing something?

Julian
  • 5,290
  • 1
  • 17
  • 40
krejale
  • 25
  • 3
  • That exception is complaining about the structure of your XML Document, not about your code (I believe). Also, why do you read all the text into a string and then use a StringReader, why not stream it in from the file system. How big is the file? – Flydog57 Apr 22 '23 at 06:34
  • This was for checking purposes. In release i will load this directliy from filestream. The structure must be correct, otherwise this would not work on windows. – krejale Apr 22 '23 at 06:55
  • Are you using same version of Net on both Windows and Apple? Is path a file or a URL? – jdweng Apr 22 '23 at 07:07
  • What does the file contain? What is the XML? Have you verified this? It is complaining about the XML, which you aren't showing us. – Marc Gravell Apr 22 '23 at 07:15
  • 1
    To be clear: when it says "root element is missing", it means *in the XML file*. That could be because the file isn't valid XML, or could be because the root element isn't the right element name (and, importantly, XML namespace matters in naming) – Marc Gravell Apr 22 '23 at 08:39
  • @MarcGravell : Op says it works on Windows so xml should be good. – jdweng Apr 22 '23 at 09:14
  • 1
    How about showing the XML that you're trying to deserialize? @jdweng The XML can still be malformed. – Julian Apr 22 '23 at 09:17
  • @ewerspej : The error is at line 0, character 0. It worked on Windows. It is not the XML. – jdweng Apr 22 '23 at 09:27
  • 3
    @jdweng Could be an encoding issue, maybe the byte order mark: https://stackoverflow.com/questions/1772321/what-is-xml-bom-and-how-do-i-detect-it – Julian Apr 22 '23 at 11:09
  • 1
    Open both XML files (the one in the Windows file system and the one on Android) as if they were binary files. Look to see if the first few bytes are the same – Flydog57 Apr 22 '23 at 19:59
  • 2
    @jdweng do you know what I'd want to do to conclude that it is not the XML? I'd want to ***look at the XML***. Clearly something unexpected is happening, so step zero is to check our assumptions, the most immediately obvious here being: what we think the file contains vs what it actually contains. If it is byte-for-byte identical, fine, but: *let's actually go check that* – Marc Gravell Apr 22 '23 at 21:12
  • @MarcGravell : I agree. Too many responses were assuming the structure of the xml was bad when it could be the user is not reading the xml. – jdweng Apr 23 '23 at 10:21
  • @jdweng with this kind of problem, it's always useful to see the XML in question and then work from there. Assumptions based on missing information are not useful. – Julian Apr 23 '23 at 10:27
  • @ewerspej : I usually agree that seeing the xml is helpful. In this case too many responses when saying the xml structure was bad instead of concentrating on the fact the user was reading the same xml with failed code. – jdweng Apr 23 '23 at 11:12
  • @jdweng We can only **safely** conclude that the XML isn't the problem, if we see it. Otherwise, it's merely an assumption. I've already seen plenty of XML parsing issues where similar errors were caused by typos and incorrect closing of root nodes, etc. It's **probably** the encoding and the BOM, but we won't know for sure until the OP provides additional information, such as an XML sample for reproduction and information about the first few bytes on each platform. – Julian Apr 23 '23 at 11:43
  • There are some cases which have the same error message as yours. In addition, can you show the code in the xml? – Liyun Zhang - MSFT Jun 06 '23 at 09:36

1 Answers1

0

The problem you're having most likely is caused by the UTF-8 byte order mark (BOM) at the beginning of the file, which the XML serializer cannot deal with.

One way to handle this is to check if the BOM is present and then remove it before parsing or deserializing the string (similar to how it is done in this answer).

For this, you can create a sanitizer extension method like this:

public static string RemoveByteOrderMark(this string str)
{
    var bom = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
    return str.StartsWith(bom) ? str.Remove(0, bom.Length) : str;    
}

Then use that before deserializing the XML:

var serializer = new XmlSerializer(typeof(AppModel));
var txt = File.ReadAllText(path);
if (txt.Length > 0)
{
    var sanitizedTxt = txt.RemoveByteOrderMark();

    using (var stringReader = new StringReader(sanitizedTxt))
    {
        var ret = (AppModel)serializer.Deserialize(stringReader);
        return ret;
    }
}

This should solve the problem for Android.

Julian
  • 5,290
  • 1
  • 17
  • 40