简体   繁体   English

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

[英]How can i generate not specified data from xml while deserialize it?

I have xml like this: 我有这样的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>

And deserialize it this way: 并以这种方式反序列化:

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();
}

As you can see, 3rd student don't have Priority and Group. 如您所见,第三名学生没有优先级和分组。 If this values is not specified, i must set random values instead. 如果未指定此值,则必须设置随机值。 What is propper way to do this? 什么是正确的方法?

I can check all deserialized data after deserialization but it sounds dumb. 反序列化后,我可以检查所有反序列化的数据,但听起来很蠢。

Checking data after deserialization is not dumb. 反序列化后检查数据不是很愚蠢。

Since you're not using a relational database or, in other words - a structured persistence provider I would say that a data check after deserialization is required . 因为您没有使用关系数据库,或者换句话说,不是结构化的持久性提供程序,所以我说反序列化之后需要进行数据检查。

The file you are reading from can be altered by other applications from the system or directly by the users so in order to avoid a NullReferenceException later in the flow (and implicitly an application crash) you need to verify/normalize your data. 您正在读取的文件可以由系统中的其他应用程序更改,也可以由用户直接更改,因此为了避免稍后在流中导致NullReferenceException (并且隐式地导致应用程序崩溃),您需要验证/规范化数据。

As a suggestion, you can create two extension methods for that: 作为建议,您可以为此创建两个扩展方法:

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();
    }
}

And in your Main method simply use: 在您的Main方法中,只需使用:

inData.Students.Normalize();

I'm still fiddeling around on how to normalize your data before serialization but a quick and dirty way to do it afterwards would be something along those lines: 我仍在思考如何在序列化之前对数据进行规范化,但是事后快速而又肮脏的方式将遵循这些原则:

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);
                });

Edit: If you really want to normalize before you serialize, you can do this: 编辑:如果您真的想在序列化之前进行规范化,则可以执行以下操作:

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));
}

Here you are checking if the elements Group and Priority exist. 在这里,您要检查元素组和优先级是否存在。 If they do not - you add them in a foreach loop. 如果没有,则将它们添加到foreach循环中。 If we want to be super precise, we'd also need to add the Id and set it to 0 like every one elses Id. 如果我们想变得非常精确,我们还需要添加ID并将其设置为0,就像其他每个ID一样。

I'm pretty sure that if you set random data in your class constructor it will be overwritten if there is data available in the Xml file and not if there is none. 我很确定,如果您在类构造函数中设置了随机数据,那么如果Xml文件中有可用数据,那么它将被覆盖,如果没有,则不会被覆盖。

This way only those items that do not have an Xml counterpart will end up having random data. 这样,只有那些没有Xml对应项的项目最终才具有随机数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM