Search code examples
c#.netxml-serialization

XML serialisation for class properties with additional meta data


I have an entity as below

public class Vehicle{
    public int VehicleId {get;set;};
    public string Make {get;set;};
    public string Model{get;set;}
}

I wanted to serialize as below

<Vehicle>
   <VehicleId AppliesTo="C1">1244</VehicleId>
   <Make AppliesTo="Common" >HXV</Make>
   <Model AppliesTo="C2">34-34</Model>
</Vehicle>

I have around 100 properties like this in Vehicle class, for each vehicle property I wanted to attach a metadata ApplieTo which will be helpful to downstream systems. AppliesTo attribute is static and its value is defined at the design time. Now How can I attach AppliesTo metadata to each property and inturn get serialized to XML?


Solution

  • You can use XElement from System.Xml.Linq to achieve this. As your data is static you can assign them easily. Sample code below -

    XElement data= new XElement("Vehicle",
                   new XElement("VehicleId", new XAttribute("AppliesTo", "C1"),"1244"),
                   new XElement("Make", new XAttribute("AppliesTo", "Common"), "HXV"),
                   new XElement("Model", new XAttribute("AppliesTo", "C2"), "34 - 34")
                   );
      //OUTPUT
      <Vehicle>
       <VehicleId AppliesTo="C1">1244</VehicleId>
       <Make AppliesTo="Common">HXV</Make>
       <Model AppliesTo="C2">34 - 34</Model>
      </Vehicle>
    

    If you are not interested in System.Xml.Linq then you have another option of XmlSerializer class. For that you need yo define separate classes for each property of vehicle. Below is the sample code and you can extend the same for Make and Model -

    [XmlRoot(ElementName = "VehicleId")]
    public class VehicleId
    {
        [XmlAttribute(AttributeName = "AppliesTo")]
        public string AppliesTo { get; set; }
        [XmlText]
        public string Text { get; set; }
    }
    
    
    [XmlRoot(ElementName = "Vehicle")]
    public class Vehicle
    {
        [XmlElement(ElementName = "VehicleId")]
        public VehicleId VehicleId { get; set; }
        //Add other properties here
    }
    

    Then create test data and use XmlSerializer class to construct XML -

    Vehicle vehicle = new Vehicle
             {
                VehicleId = new VehicleId
                  {
                     Text = "1244",
                     AppliesTo = "C1",
                  }
             };
    
    XmlSerializer testData = new XmlSerializer(typeof(Vehicle));            
    var xml = "";
    
    using (var sww = new StringWriter())
       {
          using (XmlWriter writer = XmlWriter.Create(sww))
           {
              testData.Serialize(writer, vehicle);
              xml = sww.ToString(); // XML 
           }
        }