【问题标题】:Read nodes of a xml file in C#在 C# 中读取 xml 文件的节点
【发布时间】:2017-09-28 18:34:56
【问题描述】:

如何将以下 xml 文件读入列表:

部分 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; }
}

在将子节点读入列表后,我想将其返回并显示在 DataGridView 中。

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

【问题讨论】:

  • 看起来不错,有什么问题?
  • 是你需要阅读Fragments的问题吗? msdn.microsoft.com/en-us/library/…
  • 问题是它没有返回数据,即消息,2016 年 10 月 13 日上午 11:15:00,不适用,发送“需要的订单”电子邮件。等等……
  • 您正在使用 GetAttribute 它将获取属性的值而不是节点内容的值。 (即。.

标签: c# xml winforms datagridview


【解决方案1】:

您的日志文件不是 XML 文档。由于 XML 文档必须只有一个 root element,因此它是一系列连接在一起的 XML 文档。通过设置XmlReaderSettings.ConformanceLevel == ConformanceLevel.FragmentXmlReader可以读取这样的一系列文档。完成后,您可以通读文件并使用 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

注意事项:

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

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

  • 根据documentationXmlTextReader

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

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

  • &lt;ApplicationLogEventObject&gt; 的子节点是元素而不是属性,因此 XmlReader.GetAttribute() 不是读取它们的合适方法。

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

【讨论】:

  • 非常感谢 dbc 的代码和解释,不胜感激。
  • 我只想在本周末或下周初测试代码,如果它回答了我的问题,看看你的代码,它确实应该,我一定会标记你的答案作为我的问题的解决方案;-)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 2010-11-14
  • 2020-01-13
  • 1970-01-01
相关资源
最近更新 更多