Десериализация XML дает структуру, но не данные в C # - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь десериализовать XML-файл.Получение структуры, но нет данных.Пожалуйста, помогите.

Ниже приведены файлы / классы, которые я использую:

1.Файл XML:

<?xml version="1.0" encoding="utf-8"?>
<Model     
  Content="ByBlock">
  <Units>
    <Unit
      UnitCategory="acceleration"
      Units="m/s2,cm/s2,ft/s2,g0" />   
    <Unit
      UnitCategory="angle"
      Units="radians,degrees,grads" />    
  </Units>
  <Modules>
    <Module
      Module="ControlValve">
      <Parameter
        Name="ValveCharacteristic"
        Type="Int">
        <Enumeration
          Tag="Parabolic"
          Value="4" />
        <Enumeration
          Tag="Hyperbolic"
          Value="5" />
      </Parameter>
      <Parameter
        Name="ValveCvOption"
        Type="Int">
        <Enumeration
          Tag="Set manually"
          Value="0" />
        <Enumeration
          Tag="Set from valve type and size"
          Value="1" />
      </Parameter>     
    </Module>
    <Module
      Module="Drum">
      <Parameter
        Name="VesselOrientation"
        Type="Int">
        <Enumeration
          Tag="Horizontal cylinder"
          Value="0" />
        <Enumeration
          Tag="Vertical cylinder"
          Value="1" />       
      </Parameter>
    </Module>
  </Modules>
  <Blocks>
  <Block
    ID="0"       
    Module="Drum">
    <Parameter
      Name="Diameter"         
      Value="1000.000000"/>
    <Parameter
      Name="Length"         
      Value="4000.000000"/>    
  </Block>
  <Block
    ID="0"        
    Module="ContinuousFlowCompressor">
    <Parameter
      Name="NominalSpeed"         
      Value="8950.000000"/>
    <Parameter
      Name="NominalFlow"         
      Value="2.783039" />   
  </Block>  
</Blocks>
  </Model>

2: Классы:

a.Класс модели:

[XmlRoot("Model")]
public class Model
{     
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

    [XmlArray("Units")]
    [XmlArrayItem("Unit")]
    public List<Unit> Units { get; set; }

    [XmlArray("Modules")]
    [XmlArrayItem("Module")]
    public List<Module> Modules { get; set; }

    [XmlArray("Blocks")]
    [XmlArrayItem("Block")]
    public List<Block> Blocks { get; set; }
}

б.Класс единицы:

[XmlRoot(ElementName = "Unit")]
public class Unit
{
    [XmlAttribute(AttributeName =  "UnitCategory")]
    public string UnitCategory { get; set; }
    [XmlAttribute(AttributeName =  "Units")]
    public string Units { get; set; }       
}

c.Класс модуля:

[XmlRoot(ElementName = "Module")]
public class Module
{
    [XmlAttribute(AttributeName = "Module")]
    public string Modul { get; set; }

    [XmlArrayItem("Parameter")]
    public List<ModuleParameter> Parameters { get; set; }        
}

d.ModuleParameter class:

[XmlRoot(ElementName = "Parameter")]
public class ModuleParameter
{
    [XmlAttribute(AttributeName =  "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName =  "Type")]

    public string Type { get; set; }
    [XmlArrayItem("Enumeration")]
    public List<Enumeration> Enumerations { get; set; }        
}

e.Класс перечисления:

[XmlRoot(ElementName = "Enumeration")]
public class Enumeration
{
    [XmlAttribute(AttributeName = "Tag")]
    public string Tag { get; set; }

    [XmlAttribute(AttributeName =  "Value")]
    public string Value { get; set; }       
}

f.Класс блока:

[XmlRoot(ElementName = "Block")]
public class Block
{
    [XmlAttribute(AttributeName =  "ID")]
    public string ID { get; set; }       

    [XmlAttribute(AttributeName =  "Module")]
    public string Module { get; set; }

    [XmlArrayItem("Parameter")]
    public List<BlockParameter> Parameters { get; set; }       
}

г.Класс BlockParameter:

[XmlRoot(ElementName = "Parameter")]
public class BlockParameter
{
    [XmlAttribute(AttributeName =  "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName =  "Value")]
    public string Value { get; set; }        
}

Я использую приведенный ниже код для десериализации XML-файла:

var serializer = new XmlSerializer(typeof(Model));
using (FileStream fs = File.OpenRead(file))
{
    var xmlClass = (Model)serializer.Deserialize(fs);
}

PS: 1. Обратите внимание, я должен использовать два класса параметров: один в модулеи еще один в классе блоков.2. Я изменил свой XmlElement на XmlAttribute для предлагаемых свойств, таких как Content, UnitCategory, Units и т. Д.

Ответы [ 3 ]

0 голосов
/ 23 мая 2018

Чтобы получить значения атрибутов тега, измените «Элемент XML» на "XML Attribute"

EG:

[XmlElement(ElementName = "UnitCategory")]
public string UnitCategory { get; set; }

на

[XmlAttribute(AttributeName = "UnitCategory")]
public string UnitCategory { get; set; }

Otherполя, требующиеизменить тег, имя, тип и т. д.

если вы создаете XMl путем сериализации, тогда прочитайте this

0 голосов
/ 23 мая 2018

Должно быть так:

[XmlRoot("Model")]
public class Model
{
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

    [XmlArray("Units")]
    [XmlArrayItem("Unit")]
    public List<Unit> Units { get; set; }

    [XmlArray("Modules")]
    [XmlArrayItem("Module")]
    public List<Module> Modules { get; set; }

    [XmlArray("Blocks")]
    [XmlArrayItem("Block")]
    public List<Block> Blocks { get; set; }
}

[XmlRoot(ElementName = "Unit")]
public class Unit
{
    [XmlAttribute(AttributeName = "UnitCategory")]
    public string UnitCategory { get; set; }

    [XmlAttribute(AttributeName = "Units")]
    public string Units { get; set; }
}


[XmlRoot(ElementName = "Module")]
public class Module
{
    [XmlAttribute(AttributeName = "Module")]
    public string Modul { get; set; }

    [XmlElement("Parameter")]
    public List<ModuleParameter> Parameters { get; set; }
}

[XmlRoot(ElementName = "Parameter")]
public class ModuleParameter
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "Type")]
    public string Type { get; set; }

    [XmlElement("Enumeration")]
    public List<Enumeration> Enumerations { get; set; }
}

[XmlRoot(ElementName = "Enumeration")]
public class Enumeration
{
    [XmlAttribute(AttributeName = "Tag")]
    public string Tag { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Block")]
public class Block
{
    [XmlAttribute(AttributeName = "ID")]
    public string ID { get; set; }

    [XmlAttribute(AttributeName = "Module")]
    public string Module { get; set; }

    [XmlElement("Parameter")]
    public List<BlockParameter> Parameters { get; set; }
}

[XmlRoot(ElementName = "Parameter")]
public class BlockParameter
{
    [XmlAttribute(AttributeName = "Name")]
    public string Name { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

Объяснение: массивы / списки без "контейнеров" должны быть помечены как XmlElement.Для примера: <Module> имеет контейнер <Modules>, а <Parameter> не имеет контейнера.Он напрямую добавляется к родительскому элементу.

Примечание: , как отмечает @bommelding, вы можете удалить все атрибуты [XmlRoot(...)].Они не нужны.Единственное, что нужно - это класс Model, но этот класс уже имеет имя корневого элемента.

0 голосов
/ 23 мая 2018

Одно исправление, атрибут не является элементом.
Вы можете найти другие вхождения

[XmlRoot("Model")]
public class Model
{       
    //[XmlElement(ElementName = "Content")]
    [XmlAttribute(AttributeName = "Content")]
    public string Content { get; set; }

Вы также можете добавить пустой файл C # и выбрать «Редактировать |Специальная паста |XML как классы.Не самый красивый код, но, по крайней мере, он будет действительным.Полезно для сравнения.

...