Extracting Data from XML to List<>

2019-08-27 17:17发布

问题:

I have this XML file:

<?xml version="1.0" encoding="utf-8" ?>
<Record>
  <File name="1.mot">
    <Line address="040004" data="0720" />
    <Line address="040037" data="31" />
    <Line address="04004C" data="55AA55AA" />
  </File>
  <File name="2.mot">
    <Line address="00008242" data="06" />
    <Line address="00008025" data="AFC8" />
    <Line address="00009302" data="476F6C64" />
  </File>
</Record>

What I want to do is to extract the information from the XML and convert that to list. Although I kind of don't know where and how to start. I've googled samples, and questions and the code below is what I've managed to construct so far. I'm not even sure if this code is appropriate for what I wanted to happen. This list will be used for some kind of lookup in the program. Like in file 1.mot, program would read 1.mot, read the xml file, parse both files, extract the info from the xml file and then do a search function to verify if the info in the xml exists in 1.mot.

XElement xmlReqs = XElement.Load("XMLFile1.xml");
List<Requirement> reqs = new List<Requirement>();
foreach (var xmlReq in xmlReqs.Elements("File"))
{
    string name = xmlReqs.Attribute("name").Value);
    List<InfoLine> info = new List<InfoLine>();
    foreach (var xmlInfo in xmlReq.Elements("Line"))
    {
      string address = xmlProduct.Attribute("address").Value;
      string data = xmlProduct.Attribute("data").Value;
    }
reqs.Add(new Requirement(address, data));
}

A friend of mine suggested something about using int array or string array and then using this reqs.Find(val => val[0]==target) but I'm not sure how to do so. I'm not well-versed with linq, but what I've gathered, it seems to be quite notable and powerful (?).

Anyway, will the code above work? And how do I call the objects from the list to use for the lookup function of the program?

UPDATE: Program would be reading 1.mot or 2.mot (depending on the user preference, that's why file name in xml needs to be specified) simultaneously (or not) with the xml file. 1.mot file contains:

S0030000FC
S21404000055AA55AA072000010008000938383138D7
S21404001046305730343130302020202027992401B0
...

Address starts at the 3rd byte. So yeah, would be comparing the data to these bunch of lines.

回答1:

You can de-serialize the xml file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace ConsoleApplication2
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlSerializer xs = new XmlSerializer(typeof(Record));
            XmlTextReader reader = new XmlTextReader(FILENAME);
            Record record = (Record)xs.Deserialize(reader);

        }
    }
    [XmlRoot("Record")]
    public class Record
    {
        [XmlElement("File")]
        public List<File> files {get;set;}
    }
    [XmlRoot("File")]
    public class File
    {
        [XmlAttribute("name")]
        public string name { get; set; }
        [XmlElement("Line")]
        public List<Line> lines {get;set;}
    }
    [XmlRoot("Line")]
    public class Line
    {
        [XmlAttribute("address")]
        public string address {get;set;}
        [XmlAttribute("data")]
        public string data {get;set;}
    }
}
​


回答2:

You could use XmlSerializer to handle the reading of the XML. Create some classes that look like these:

public class Record
{
    [XmlElement("File")]
    public List<File> Files { get; set; }
}

public class File
{
    [XmlAttribute("name")]
    public string Name { get; set; }

    [XmlElement("Line")]
    public List<Line> Lines { get; set; } 
}

public class Line
{
    [XmlAttribute("address")]
    public int Address { get; set; }

    [XmlAttribute("data")]
    public string Data { get; set; }
}

And deserialise like so:

var serializer = new XmlSerializer(typeof (Record));

using (var reader = XmlReader.Create("XMLFile1.xml"))            
{
    var record = (Record) serializer.Deserialize(reader);

    var first = record.Files.Single(f => f.Name == "1.mot");
    var second = record.Files.Single(f => f.Name == "2.mot");
}