在C#中读取xml文件的节点 [英] Read nodes of a xml file in C#
问题描述
如何将以下xml文件读入列表:
How can I read the following xml file into a List:
部分XML文件(data.log)
Partial XML file (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):
And here is the data access layer (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文件中的子元素:
And the Data Types which will hold the child elements from the XML file:
public class ApplicationLogEventObject
{
public string EventType { get; set; }
public DateTime DateStamp { get; set; }
public string ShortDescription { get; set; }
public string LongDescription { get; set; }
}
将子节点读入列表后,我想返回并显示在DataGridView中。
After I've read the child nodes into a List I would then like to return it and display it in a DataGridView.
有关此问题的任何帮助将不胜感激。
Any help regarding this question will be much appreciated.
推荐答案
您的日志文件不是XML文档。由于XML文档必须只有一个根元素,因此它是一系列XML文档的串联一起。可以通过 XmlReader
通过设置 XmlReaderSettings.ConformanceLevel == ConformanceLevel.Fragment
。这样做后,您可以使用 XmlSerializer
如下:
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;
}
使用以下版本的 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小提琴。
注意:
-
< DateStamp>
元素值2016/10/13上午11:15:00
对于XML中的日期和时间格式不正确,即 ISO 8601 。因此,我引入了一个代理string DateStampString
属性来手动处理所需格式的转换,然后标记原始的DateTime
具有XmlIgnore
。
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
.
使用 ReadSubtree()
防止读取超过每个根元素末尾的可能性
Using ReadSubtree()
prevents the possibility of reading past the end of each root element when the XML is not indented.
根据文档,用于 XmlTextReader
:
从.NET Framework 2.0开始,建议您改用System.Xml.XmlReader类。
Starting with the .NET Framework 2.0, we recommend that you use the System.Xml.XmlReader class instead.
因此,我建议将这种类型的使用替换为 XmlReader
。
Thus I recommend replacing use of that type with XmlReader
.
< ApplicationLogEventObject>
的子节点是元素而不是属性,因此 XmlReader.GetAttribute()
不是用于读取它们的合适方法。
The child nodes of your <ApplicationLogEventObject>
are elements not attributes, so XmlReader.GetAttribute()
was not an appropriate method to use to read them.
鉴于您的日志文件未按照ISO 8601格式设置时间,因此至少应确保将其格式设置为文化上不变的格式,以便可以在具有不同区域性的计算机之间交换日志文件设置。使用 CultureInfo进行转换。 InvariantCulture
确保了这一点。
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.
这篇关于在C#中读取xml文件的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!