简体   繁体   English

C#中的XML序列化和反序列化

[英]XML Serialization and Deserialization in C#

<job id="ID00004" name="PeakValCalcO">
  <uses file="Seismogram_FFI_0_1_ID00003.grm" link="input" />
  <uses file="PeakVals_FFI_0_1_ID00003.bsa" link="output" />
</job>
<job id="ID00005" name="SeismogramSynthesis" >
  <uses file="FFI_0_1_txt.variation-s07930-h00000" link="input" />
  <uses file="Seismogram_FFI_0_1_ID00005.grm" link="output" />
</job>

Let say I have this XML I want to convert into .net Object how can do this i tried it but it doesn't work correct... 可以说我有要转换为.net对象的XML,我试过怎么办,但无法正常工作...

public class jobs : List<job> { }

    public class job
    {
        public string id { get; set; }
        public string name { get; set; }
        public List<uses> Files { get; set; }
    }
    public class uses
    {
        public string file { get; set; }
        public string link { get; set; }
    }



 private void Form1_Load(object sender, EventArgs e)
        {

           XmlSerializer serializer = new XmlSerializer(typeof(jobs)); 
           TextReader tr = new StreamReader("CyberShake_100.xml"); 
           job b = (job)serializer.Deserialize(tr); 
           tr.Close(); 
    }

You need to understand that id and name on <jobs> are XML attributes - you need to express that in your classes, too: 您需要了解<jobs>上的idname是XML属性-您也需要在类中表达这一点:

public class job
{
    [XmlAttribute]
    public string id { get; set; }
    [XmlAttribute]
    public string name { get; set; }
    public List<uses> Files { get; set; }
}

The same applies to your <uses> tag and its class representation. 这同样适用于您的<uses>标记及其类表示。

Also: a valid XML document always has one root element and one root only - your XML fragment is not a valid XML document. 另外:有效的XML文档始终只有一个根元素和一个根-您的XML片段不是有效的XML文档。

Hmm, there are several things wrong here: 嗯,这里有几处错误:

1) Your xml document has no root element 1)您的xml文档没有根元素

It needs to look more like this: 它需要看起来像这样:

<jobs>
  <job id="ID00004" name="PeakValCalcO">
    <uses file="Seismogram_FFI_0_1_ID00003.grm" link="input" />
    <uses file="PeakVals_FFI_0_1_ID00003.bsa" link="output" />
  </job>
  <job id="ID00005" name="SeismogramSynthesis" >
    <uses file="FFI_0_1_txt.variation-s07930-h00000" link="input" />
    <uses file="Seismogram_FFI_0_1_ID00005.grm" link="output" />
  </job>
</jobs>

2) You need some xml serialisation attributes 2)您需要一些xml序列化属性

Attributes are used to tell the .Net framework how to serialise and deserialise xml . 属性用于告诉.Net框架如何序列化和反序列化xml Without these the .Net frameowork is just guessing at your xml format, and so won't do a very good job. 没有这些,.Net框架只能猜测您的xml格式,因此不会做得很好。 In this case you need: 在这种情况下,您需要:

  • An XmlRoot attribute on your jobs class to tell the .Net framework what your root element type is jobs类上的XmlRoot属性,用于告诉.Net框架您的根元素类型是什么
  • Some XmlAttribute attributes to indicate which properties are serialised as attributes 一些XmlAttribute属性指示哪些属性被序列化为属性
  • A XmlElement attribute to indicate that your array is serialised as a "flat" sequence of elements rather than as a nested array (and what those elements are called). 一个XmlElement属性,指示您的数组被序列化为元素的“扁平”序列,而不是嵌套的数组(以及这些元素的名称)。

Combine all of this and your classes should look like this: 结合所有这些,您的类应如下所示:

[XmlRoot("jobs")]
public class jobs : List<job> { }

public class job
{
    [XmlAttribute]
    public string id { get; set; }
    [XmlAttribute]
    public string name { get; set; }
    [XmlElement("uses")]
    public List<uses> Files { get; set; }
}

public class uses
{
    [XmlAttribute]
    public string file { get; set; }
    [XmlAttribute]
    public string link { get; set; }
}

For complex xml document this tends to get a bit tedious - there is a tool XSD.exe that will automate all of this for you. 对于复杂的xml文档,这往往会有些乏味-有一个工具XSD.exe将为您自动完成所有这些工作。

3) You are casting to the wrong type 3)您投放的类型错误

Even if the serialisation succeeds you will get an InvalidCastExcpetion trying to cast a jobs instance to job . 即使系列化成功,你会得到一个InvalidCastExcpetion试图铸造的jobs实例来job Try this instead: 尝试以下方法:

using (TextReader tr = new StreamReader("CyberShake_100.xml"))
{
    jobs b = (jobs)serializer.Deserialize(tr);
}

You can use the XSD.exe tool to generate a class structure that matches your XML. 您可以使用XSD.exe工具生成与XML匹配的类结构。 It is probably the easiest way to have a working serialization object hierarchy. 这可能是拥有有效的序列化对象层次结构的最简单方法。

At least you need the [XmlAttribute] on id, name, file and link members. 至少您需要ID,名称,文件和链接成员上的[XmlAttribute]

You also cast to the wrong type, should be jobs b = (jobs)serializer.Deserialize(tr); 您还转换为错误的类型,应为jobs b = (jobs)serializer.Deserialize(tr);

This is not a valid XML document, since it has more than a single root. 这不是有效的XML文档,因为它具有多个根目录。 That's the reason you can't use something out-of-the-box from the framework. 这就是您不能从框架中直接使用某些东西的原因。

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

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