Search code examples
c#xmlxmlreader

Why xmlreader can't read something that xmlwriter wrote?


I have the simplest code in the world,

using (XmlWriter writer = XmlWriter.Create(stringWriter))
{
 writer.WriteStartDocument();
 writer.WriteStartElement("Board");
 writer.WriteAttributeString("Rows", mRows.ToString());
 writer.WriteAttributeString("Columns", mColumns.ToString());
 writer.WriteEndElement();
 writer.WriteEndDocument();
}
TextWriter writer1 = new StreamWriter(path);
writer1.Write(stringWriter.toString());
writer1.Close();

Then i write it to a txt file that looks like this:

<?xml version="1.0" encoding="utf-16"?>
<Board Rows="30" Columns="50">
</Board>

Then i do the following :

FileStream str = new FileStream(s.FileName, FileMode.Open);
using(XmlReader reader = XmlReader.Create(stream))
{
reader.Read();
}

And it throws an exception :

"There is no Unicode byte order mark. Cannot switch to Unicode."

I googled the exception and found several workarounds, but i don't understand why i need a work around, i just want to read the xml i wrote. Can some one please explain what exactly the problem is ? Should i write something differently in the xml ?

What is the simplest solution to this ?


Solution

  • You're probably not writing to a unicode file which File.WriteAllText or a vanilla FileStream does not do.

    Instead use File.OpenWrite or FileStream combined with the StreamWriter(Stream steam, Encoding encoding) constructor to specify unicode.

    Sample:

    var path = @"C:\Dev\sample.xml";
    
    string xml;
    
    var mRows = 30;
    var mColumns = 50;
    
    var options = new XmlWriterSettings { Indent = true };
    
    using (var stringWriter = new StringWriter())
    {
        using (var writer = XmlWriter.Create(stringWriter, options))
        {
            writer.WriteStartDocument();
            writer.WriteStartElement("Board");
            writer.WriteAttributeString("Rows", mRows.ToString());
            writer.WriteAttributeString("Columns", mColumns.ToString());
            writer.WriteEndElement();
            writer.WriteEndDocument();
        }
        xml = stringWriter.ToString();
    }
    
    if(File.Exists(path))
        File.Delete(path);
    
    using(var stream = File.OpenWrite(path))
    using(var writer = new StreamWriter(stream, Encoding.Unicode))
    {
        writer.Write(xml);
    }
    
    
    Console.Write(xml);
    
    using(var stream = File.OpenRead(path))
    using(var reader = XmlReader.Create(stream))
    {
        reader.Read();
    }
    
    File.Delete(path);