Сериализация и десериализация XML в C # - PullRequest
0 голосов
/ 22 февраля 2011
<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>

Допустим, у меня есть этот XML, который я хочу преобразовать в .net Object. Как я могу это сделать, я попробовал, но он работает неправильно ...

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

Ответы [ 5 ]

2 голосов
/ 22 февраля 2011

Хм, здесь есть несколько неправильных вещей:

1) Ваш XML-документ не имеет корневого элемента

Он должен выглядеть примерно так:

<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) Вам нужны некоторые атрибуты сериализации xml

Атрибуты используются для , чтобы сообщить .Net Framework, как сериализовать и десериализовать xml .Без этого .Net frameowork просто догадывается о вашем формате XML, и поэтому не будет очень хорошей работы.В этом случае вам нужно:

  • атрибут XmlRoot в вашем классе jobs, чтобы сообщить .Net Framework, какой тип корневого элемента у вас есть
  • Для некоторых атрибутов XmlAttributeукажите, какие свойства сериализуются как атрибуты
  • Атрибут XmlElement, чтобы указать, что ваш массив сериализуется как «плоская» последовательность элементов, а не как вложенный массив (и как эти элементы называются).

Объедините все это, и ваши классы должны выглядеть следующим образом:

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

Для сложного XML-документа это может быть немного утомительным - есть инструмент XSD.exe, который будет автоматизироватьвсе это для вас.

3) Вы используете неправильный тип

Даже если сериализация завершится успешно, вы получите InvalidCastExcpetion, пытаясь разыграть jobs экземпляр job.Попробуйте вместо этого:

using (TextReader tr = new StreamReader("CyberShake_100.xml"))
{
    jobs b = (jobs)serializer.Deserialize(tr);
}
2 голосов
/ 22 февраля 2011

Вы должны понимать, что id и name на <jobs> являются атрибутами XML - вы должны выразить это и в своих классах:

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

То же самое относится к вашему тегу <uses> и его представлению класса.

Также: действительный документ XML всегда имеет один корневой элемент и только один корень - ваш фрагмент XML не является действительным документом XML.

1 голос
/ 22 февраля 2011

Как минимум, вам нужно [XmlAttribute] для идентификатора, имени, файла и членов ссылки.

Вы также приводите неверный тип, должно быть jobs b = (jobs)serializer.Deserialize(tr);

1 голос
/ 22 февраля 2011

Вы можете использовать инструмент XSD.exe, чтобы сгенерировать структуру класса, соответствующую вашему XML. Вероятно, это самый простой способ иметь работающую иерархию объектов сериализации.

0 голосов
/ 22 февраля 2011

Это недопустимый документ XML, так как он имеет более одного корня.Вот почему вы не можете использовать что-то из коробки из фреймворка.

...