在C#中读取xml文件的节点

如何将以下xml文件读入List:

部分XML文件(data.log)

 Message 10/13/2016 11:15:00 AM N/A Sending 'required orders' email.   Message 10/13/2016 11:15:10 AM N/A Branches Not Placed Orders - 1018   Message 10/13/2016 11:15:10 AM N/A Branches Not Placed Orders - 1019  ... 

这是数据访问层(DAL):

 public List Get() { try { XmlTextReader xmlTextReader = new XmlTextReader(@"C:\data.log"); List recordSet = new List(); 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中显示。

任何关于这个问题的帮助将不胜感激。

您的日志文件不是XML文档。 由于XML文档必须只有一个根元素 ,因此它是一系列连接在一起的XML文档。 XmlReader通过设置XmlReaderSettings.ConformanceLevel == ConformanceLevel.Fragment来读取这一系列文档。 完成后,您可以读取文件并使用XmlSerializer单独反序列化每个根元素,如下所示:

 static List ReadEvents(string fileName) { return ReadObjects(fileName); } static List ReadObjects(string fileName) { var list = new List(); 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小提琴 。

笔记:

  • 10/13/2016 11:15:00 AM 元素值10/13/2016 11:15:00 AM在XML中的日期和时间格式不正确,即ISO 8601 。 因此,我引入了一个代理string DateStampString属性来手动处理所需格式的转换,然后使用XmlIgnore标记原始DateTime属性。

  • 使用ReadSubtree()可防止在XML未缩进时读取每个根元素末尾的可能性。

  • 根据XmlTextReader的文档 :

    从.NET Framework 2.0开始,我们建议您使用System.Xml.XmlReader类。

    因此,我建议用XmlReader替换该类型的使用。

  • 的子节点是元素而不是属性,因此XmlReader.GetAttribute()不是用于读取它们的适当方法。

  • 鉴于您的日志文件未在ISO 8601中格式化它们的时间,您至少应确保它们以文化不变的格式进行格式化,以便可以在具有不同区域设置的计算机之间交换日志文件。 使用CultureInfo.InvariantCulture转换可确保这一点。