如何在反序列化时从xml生成未指定的数据?

时间:2015-02-13 12:43:47

标签: c# xml

我有这样的xml:

<?xml version="1.0" encoding="utf-8"?>
<InputData>
    <MaxCPUBurst>12</MaxCPUBurst>
    <MaxPriority>30</MaxPriority>
    <Processes>
        <Student>
            <CPUBurst>12</CPUBurst>
            <Id>1</Id>
            <Priority>5</Priority>
            <Resources>2</Resources>
            <Group>1</Group>
            <Name>Sidorov Sidor Sidorovich</Name>
        </Student>
        <Student>
            <CPUBurst>11</CPUBurst
            ><Id>2</Id>
            <Priority>8</Priority>
            <Resources>1</Resources>
            <Group>2</Group>
            <Name>Olegov Oleg Olegovich</Name>
        </Student>
        <Student>
            <CPUBurst>14</CPUBurst>
            <Id>7</Id>
            <Resources>1</Resources>
            <Name>Ivanova Anastasiya Igorevna</Name>
        </Student>
    </Processes>
</InputData>

以这种方式反序列化:

public class InputData {
    public int MaxCPUBurst { get; set; }
    public int MaxPriority { get; set; }
    public int QuantDuration { get; set; }
    public string PlanningMethod { get; set; }
    public List<Student> Processes;
}

public class Student {
    public int CPUBurst { get; set; }
    public int id { get; set; }
    public int Priority { get; set; }
    public int Group { get; set; }
    public string Name { get; set; }
}

static void Main(string[] args) {
XmlDocument contentxml = new XmlDocument();
    contentxml.Load("INPUT.xml");
    XmlSerializer serializer = new XmlSerializer(typeof(InputData));
    InputData inData;
    using (StringReader reader = new StringReader(contentxml.OuterXml)) {
        inData = (InputData)(serializer.Deserialize(reader));
    }

    Console.WriteLine(inData.Processes.First().Name);
    Console.WriteLine(inData.Processes.Last().Name);
    Console.WriteLine("Press any key");
    Console.ReadLine();
}

如您所见,第3名学生没有优先级和组。如果未指定此值,则必须设置随机值。什么是适当的方法来做到这一点?

我可以在反序列化后检查所有反序列化的数据,但听起来很愚蠢。

3 个答案:

答案 0 :(得分:1)

反序列化后检查数据并不愚蠢。

由于您没有使用关系数据库,换句话说 - 结构化持久性提供程序,我会说在反序列化之后需要进行数据检查

您正在读取的文件可以由系统中的其他应用程序更改,也可以由用户直接更改,因此为了避免流程中的NullReferenceException(以及隐式的应用程序崩溃),您需要验证/规范化您的数据。

作为建议,您可以为此创建两种扩展方法:

public static class DataExtensions
{
    private static readonly Random _random = new Random();

    public static void Normalize(this List<Student> students)
    {
        for(int i=0; i<students.Count; i++)
        {
            students[i].Normalize();
        }
    }

    public static void Normalize(this Student student)
    {
        if(student.Group == 0)
            student.Group = _random.Next();
        if(student.Priority == 0)
            student.Priority = _random.Next();
    }
}

在您的Main方法中,只需使用:

inData.Students.Normalize();

答案 1 :(得分:0)

我仍然在如何在序列化之前规范化您的数据,但之后快速而肮脏的方式将是这样的:

inData.Processes.Where(x => x.Priority == 0 && x.Group == 0)
                .ToList()
                .ForEach(std => {
                    Random r = new Random();
                    std.Priority = r.Next(1,10);
                    std.Group = r.Next(1,10);
                });

编辑:如果你真的想在序列化之前进行规范化,你可以这样做:

XElement root = XElement.Load(@"path\to\xml");
XmlSerializer serializer = new XmlSerializer(typeof(InputData));
InputData inData;       

root.Elements("Processes")
    .Elements("Student")
    .Where (r => r.Element("Group") == null && r.Element("Priority") == null)
    .ToList()
    .ForEach(x => {
        Random r = new Random();
        x.Add(new XElement("Group", r.Next(1,10)));
        x.Add(new XElement("Priority", r.Next(1,10)));
    });

using (StringReader reader = new StringReader(root.ToString())) 
{
    inData = (InputData)(serializer.Deserialize(reader));
}

在这里,您要检查元素组和优先级是否存在。如果他们不这样做 - 你将它们添加到foreach循环中。如果我们想要超精确,我们还需要添加Id并将其设置为0,就像每个人一样。

答案 2 :(得分:0)

我很确定如果在类构造函数中设置随机数据,如果Xml文件中有可用数据,则会覆盖它,如果没有,则不会覆盖。

这种方式只有那些没有Xml版本的项目才会有随机数据。