如何将以下xml文件读入List:
部分XML文件(data.log)
<ApplicationLogEventObject>
<EventType>Message</EventType>
<DateStamp>10/13/2016 11:15:00 AM</DateStamp>
<ShortDescription>N/A</ShortDescription>
<LongDescription>Sending 'required orders' email.</LongDescription>
</ApplicationLogEventObject>
<ApplicationLogEventObject>
<EventType>Message</EventType>
<DateStamp>10/13/2016 11:15:10 AM</DateStamp>
<ShortDescription>N/A</ShortDescription>
<LongDescription>Branches Not Placed Orders - 1018</LongDescription>
</ApplicationLogEventObject>
<ApplicationLogEventObject>
<EventType>Message</EventType>
<DateStamp>10/13/2016 11:15:10 AM</DateStamp>
<ShortDescription>N/A</ShortDescription>
<LongDescription>Branches Not Placed Orders - 1019</LongDescription>
</ApplicationLogEventObject>
...
这是数据访问层(DAL):
public List<FLM.DataTypes.ApplicationLogEventObject> Get()
{
try
{
XmlTextReader xmlTextReader = new XmlTextReader(@"C:\data.log");
List<FLM.DataTypes.ApplicationLogEventObject> recordSet = new List<ApplicationLogEventObject>();
xmlTextReader.Read();
while (xmlTextReader.Read())
{
xmlTextReader.MoveToElement();
FLM.DataTypes.ApplicationLogEventObject record = new ApplicationLogEventObject();
record.EventType = xmlTextReader.GetAttribute("EventType").ToString();
record.DateStamp = Convert.ToDateTime(xmlTextReader.GetAttribute("DateStamp"));
record.ShortDescription = xmlTextReader.GetAttribute("ShortDescription").ToString()
record.LongDescription = xmlTextReader.GetAttribute("LongDescription").ToString();
recordSet.Add(record);
}
return recordSet;
}
catch (Exception ex)
{
throw ex;
}
}
将从XML文件中保存子元素的数据类型:
public class ApplicationLogEventObject
{
public string EventType { get; set; }
public DateTime DateStamp { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
}
在我将子节点读入List后,我想将其返回并在DataGridView中显示。
非常感谢有关此问题的任何帮助。
答案 0 :(得分:2)
您的日志文件不是XML文档。由于XML文档必须只有一个root element,因此它是一系列连接在一起的XML文档。 XmlReader
可以通过设置XmlReaderSettings.ConformanceLevel == ConformanceLevel.Fragment
来阅读这一系列文档。完成此操作后,您可以阅读文件并使用XmlSerializer
单独反序列化每个根元素,如下所示:
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;
}
使用以下版本的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; }
}
示例.Net fiddle。
注意:
<DateStamp>
元素值10/13/2016 11:15:00 AM
的格式与XML中的日期和时间格式不同,即ISO 8601。因此,我引入了代理string DateStampString
属性来手动处理所需格式的转换,然后使用XmlIgnore
标记原始DateTime
属性。
使用ReadSubtree()
可以防止在XML没有缩进时读取每个根元素的结尾。
根据XmlTextReader
的{{3}}:
从.NET Framework 2.0开始,我们建议您改用System.Xml.XmlReader类。
因此,我建议用XmlReader
替换该类型的使用。
<ApplicationLogEventObject>
的子节点是元素而非属性,因此documentation不适合用于阅读它们。
鉴于您的日志文件未在ISO 8601中格式化它们的时间,您至少应确保它们以文化不变的格式进行格式化,以便可以在具有不同区域设置的计算机之间交换日志文件。使用XmlReader.GetAttribute()
进行转换可以确保这一点。