1

Trying to deserialize a XML log file. And cannot seem to get anything but Error in XML Document(0,0). I am guessing it has something to do with my class but I cannot seem to find a solution. I cannot change the XML formatting as this is a log file coming from a server (just simplified)

XML

<?xml version="1.0" encoding="utf-8"?>
<POSLog>
<Transaction>
  <RetailStoreID>1</RetailStoreID>
  <SequenceNumber>2</SequenceNumber>
</Transaction>
<Transaction>
  <RetailStoreID>1</RetailStoreID>
  <SequenceNumber>3</SequenceNumber>
</Transaction>
</POSLog>

Class

[Serializable()]
public class Transaction
{
    [XmlElement("RetailStoreID")]
    public string RetailStoreID { get; set; }

    [XmlElement("SequenceNumber")]
    public string SequenceNumber { get; set; }

}

[Serializable()]
[XmlRoot("POSLog")]
public class POSLog
{
    [XmlArray("POSLog")]
    [XmlArrayItem("Transaction", typeof(Transaction))]
    public Transaction[] Transaction { get; set; }
}

Deserialize code

POSLog poslog = new POSLog();
string path = "POSLog.xml";
XmlSerializer serializer = new XmlSerializer(typeof(POSLog));
StreamReader reader = new StreamReader(path);
poslog = (POSLog)serializer.Deserialize(reader);

Found fix by switching from StreamReader to FileStream along with changes to the class. Changing encoding didn't seem to help when using the StreamReader.

WPete
  • 21
  • 4
  • 2
    1) Need Inner exceptions, 2) (offtopic) You use a bit too much attributes. – Kovpaev Alexey Aug 05 '16 at 15:19
  • 1
    Show the stacktrace and in particular the whole exception (the inner exception). – MakePeaceGreatAgain Aug 05 '16 at 15:24
  • 2
    Since the error is at (0,0), meaning the first character of the first line, I'm guessing it's because your XML file was encoded using UTF with a byte order mark. Try adding an Encoding to your StreamReader. – Heretic Monkey Aug 05 '16 at 15:26
  • 1
    Possible duplicate of [XmlException while deserializing xml file in UTF-16 encoding format](http://stackoverflow.com/questions/25298355/xmlexception-while-deserializing-xml-file-in-utf-16-encoding-format) – Heretic Monkey Aug 05 '16 at 15:27
  • @MikeMcCaughan - The `StreamReader` should detect & consume the BOM automatically. See the [reference source](http://referencesource.microsoft.com/#mscorlib/system/io/streamreader.cs,181) where `true` is passed for `detectEncodingFromByteOrderMarks`. – dbc Aug 05 '16 at 15:31
  • I was not able to recreate your issue, plausibly because it's the encoding issue others have mentioned. But I wasn't able to deserialize your XML because according to your attributing, your `Transaction` array is serialized as an element named `POSLog`, within the outer `POSLog` element: ``. So that issue will come up when you get the encoding squared away. – 15ee8f99-57ff-4f92-890c-b56153 Aug 05 '16 at 15:33
  • 1
    If you do [`File.ReadAllBytes()`](https://msdn.microsoft.com/en-us/library/system.io.file.readallbytes(v=vs.110).aspx) on your XML file, what are the first 20 or so bytes in the file? – dbc Aug 05 '16 at 15:42
  • 1
    Using the answer below of treating the Transaction as an Element was part of the issue, the main thing that solved my issue was using a FileStream instead of the StreamReader. Was getting inner exceptions of root element not found. Switching to the FileStream fixed the issue. – WPete Aug 05 '16 at 19:59

2 Answers2

3

I cannot reproduce the problem you are seeing. However, there is an issue with the POSLog class -- it needs to be defined as follows:

[Serializable()]
[XmlRoot("POSLog")]
public class POSLog
{
    [XmlElement("Transaction")]
    public Transaction[] Transaction { get; set; }
}   

Your XML has a root element <POSLog> containing a repeating sequence of <Transaction> elements. [XmlElement("Transaction")] maps the array to just such a one-level repeating sequence.

Example fiddle.

dbc
  • 104,963
  • 20
  • 228
  • 340
1

Changing the Class to the follow above answer

[Serializable()]
[XmlRoot("POSLog")]
public class POSLog
{
    [XmlElement("Transaction")]
    public Transaction[] Transaction { get; set; }
}   

Along with Changing the following StreamReader lines

StreamReader reader = new StreamReader(path);
poslog = (POSLog)serializer.Deserialize(reader);

To this:

FileStream fs = new FileStream(path, FileMode.Open);
poslog = (POSLog)serializer.Deserialize(fs);

Fixed the issue I was having with the root element and I was able to deserialize the XML. Thanks to dbc for help in getting me started solving a solution for the first time in a forum!

WPete
  • 21
  • 4