Reputation: 2927
I am trying to de-serialize an xml file. Getting structure but no data. Kindly help.
Below are the files/classes, I am using:
<?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>
a. Model class:
[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; }
}
b. Unit class:
[XmlRoot(ElementName = "Unit")]
public class Unit
{
[XmlAttribute(AttributeName = "UnitCategory")]
public string UnitCategory { get; set; }
[XmlAttribute(AttributeName = "Units")]
public string Units { get; set; }
}
c. Module class:
[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. Enumeration class:
[XmlRoot(ElementName = "Enumeration")]
public class Enumeration
{
[XmlAttribute(AttributeName = "Tag")]
public string Tag { get; set; }
[XmlAttribute(AttributeName = "Value")]
public string Value { get; set; }
}
f. Block class:
[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; }
}
g. BlockParameter class:
[XmlRoot(ElementName = "Parameter")]
public class BlockParameter
{
[XmlAttribute(AttributeName = "Name")]
public string Name { get; set; }
[XmlAttribute(AttributeName = "Value")]
public string Value { get; set; }
}
I am using below code to deserialize the xml file:
var serializer = new XmlSerializer(typeof(Model));
using (FileStream fs = File.OpenRead(file))
{
var xmlClass = (Model)serializer.Deserialize(fs);
}
PS: 1. Please note, I have to use two Parameter classes: One in Module & another in Block class. 2. I have modified my XmlElement to XmlAttribute for suggested properties like Content, UnitCategory, Units etc.
Upvotes: 1
Views: 492
Reputation: 111940
It should be this:
[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; }
}
Explanation: arrays/Lists without "containers" must be marked as XmlElement
. To give an example: <Module>
has as a container <Modules>
, while <Parameter>
doesn't have a container. It is directly added to the parent element.
Note: as noted by @bommelding, you can remove all the [XmlRoot(...)]
attributes. They aren't needed. The only one needed would be the one on the Model
class, but that class already has the name of the root element.
Upvotes: 1
Reputation: 1600
To get the attribute values of the tag change the the "XML Element" to "XML Attribute"
EG:
[XmlElement(ElementName = "UnitCategory")]
public string UnitCategory { get; set; }
to
[XmlAttribute(AttributeName = "UnitCategory")]
public string UnitCategory { get; set; }
Other fields which req. change are tag,name,type etc.
if you are creating the XMl by serializing then read this
Upvotes: 0
Reputation: 3037
One correction, an Attribute is not an Element.
You can find the other occurrences
[XmlRoot("Model")]
public class Model
{
//[XmlElement(ElementName = "Content")]
[XmlAttribute(AttributeName = "Content")]
public string Content { get; set; }
You can also add an empty C# file and select Edit | Paste special | XML as classes. Not the prettiest code but at least it will be valid. Useful for comparison.
Upvotes: 2