Your log file is not an XML document. Since an XML document must have one and only one root element, it’s a series of XML documents concatenated together. Such a series of documents can be read by XmlReader
by setting XmlReaderSettings.ConformanceLevel == ConformanceLevel.Fragment
. Having done so, you can read through the file and deserialize each root element individually using XmlSerializer
as follows:
static List<ApplicationLogEventObject> ReadEvents(string fileName)
{
return ReadObjects<ApplicationLogEventObject>(fileName);
}
static List<T> ReadObjects<T>(string fileName)
{
var list = new List<T>();
var serializer = new XmlSerializer(typeof(T));
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (var textReader = new StreamReader(fileName))
using (var xmlTextReader = XmlReader.Create(textReader, settings))
{
while (xmlTextReader.Read())
{ // Skip whitespace
if (xmlTextReader.NodeType == XmlNodeType.Element)
{
using (var subReader = xmlTextReader.ReadSubtree())
{
var logEvent = (T)serializer.Deserialize(subReader);
list.Add(logEvent);
}
}
}
}
return list;
}
Using the following version of ApplicationLogEventObject
:
public class ApplicationLogEventObject
{
public string EventType { get; set; }
[XmlElement("DateStamp")]
public string DateStampString {
get
{
// Replace with culturally invariant desired formatting.
return DateStamp.ToString(CultureInfo.InvariantCulture);
}
set
{
DateStamp = Convert.ToDateTime(value, CultureInfo.InvariantCulture);
}
}
[XmlIgnore]
public DateTime DateStamp { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
}
Sample .Net fiddle.
Notes:
-
The
<DateStamp>
element values10/13/2016 11:15:00 AM
are not in the correct format for dates and times in XML, which is ISO 8601. Thus I introduced a surrogatestring DateStampString
property to manually handle the conversion from and to your desired format, and then marked the originalDateTime
property withXmlIgnore
. -
Using
ReadSubtree()
prevents the possibility of reading past the end of each root element when the XML is not indented. -
According to the documentation for
XmlTextReader
:Starting with the .NET Framework 2.0, we recommend that you use the System.Xml.XmlReader class instead.
Thus I recommend replacing use of that type with
XmlReader
. -
The child nodes of your
<ApplicationLogEventObject>
are elements not attributes, soXmlReader.GetAttribute()
was not an appropriate method to use to read them. -
Given that your log files are not formatting their times in ISO 8601, you should at least make sure they are formatted in a culturally invariant format so that log files can be exchanged between computers with different regional settings. Doing your conversions using
CultureInfo.InvariantCulture
ensures this.