Search code examples
c#xmlxml-serialization

How to serialize a class property to be a part of xml root?


I have the following xml

<OTA_HotelResNotifRS xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Connect.Domain.OTA_2014B.Reservations.OTA_HotelResNotifRS">
    <HotelReservations>
        <HotelReservation>
            <ResGlobalInfo>
                <HotelReservationIDs>
                    <OTA_HotelResNotifRSHotelReservationsHotelReservationResGlobalInfoHotelReservationID>
                        <ResID_Source>some_source</ResID_Source>
                        <ResID_Type>0</ResID_Type>
                        <ResID_Value>51550</ResID_Value>
                    </OTA_HotelResNotifRSHotelReservationsHotelReservationResGlobalInfoHotelReservationID>
                </HotelReservationIDs>
            </ResGlobalInfo>
        </HotelReservation>
    </HotelReservations>
    <Success i:nil="true" />
    <Target i:nil="true" />
    <TimeStamp>0001-01-01T00:00:00</TimeStamp>
    <Version>0</Version>
</OTA_HotelResNotifRS>

With the following c# code.

    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = 

    "http://www.opentravel.org/OTA/2003/05")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.opentravel.org/OTA/2003/05", IsNullable = false)]
    public partial class OTA_HotelResNotifRS

{   
    /// <remarks/>
    public OTA_HotelResNotifRSHotelReservations HotelReservations
    {
        get; set;
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public System.DateTime TimeStamp
    {
        get; set;
    }
}

How can I place timestamp, target and version in root element? I tried to add XmlRootAttribute instead of XmlAttribute, but I am getting an error.


Solution

  • If you want to make TimeStamp and Version attributes, just add a XmlAttribute.

    [XmlAttribute]
    public DateTime TimeStamp { get; set; }
    
    [XmlAttribute]
    public byte Version { get; set; }
    

    To make the Target property as attribute, it must be a simple type, like int, DateTime, etc.

    [XmlAttribute]
    public int Target { get; set; }
    

    If it is complex type like object, etc, then will have to leave it as element.

    [XmlElement]
    public object Target { get; set; }
    

    I copied your xml to the clipboard.

    In the Visual Studio menu choose Edit > Paste Special > Paste XML As Classes. Were generated a set of classes.

    I have added the attribute [XmlAttribute] before the properties TimeStamp and Version. That's all, I have not made any other changes.

    Execute this code:

    var xs = new XmlSerializer(typeof(OTA_HotelResNotifRS));
    OTA_HotelResNotifRS ota;
    
    using (var fs = new FileStream("in.xml", FileMode.Open))
        ota = (OTA_HotelResNotifRS)xs.Deserialize(fs);
    
    using (var fs = new FileStream("out.xml", FileMode.Create))
        xs.Serialize(fs, ota);
    

    In the end, I got the following xml (I formatted the attributes for easier reading and skipped inner nodes):

    <?xml version="1.0"?>
    <OTA_HotelResNotifRS xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         TimeStamp="0001-01-01T00:00:00"
                         Version="0"
                         xmlns="http://schemas.datacontract.org/2004/07/Connect.Domain.OTA_2014B.Reservations.OTA_HotelResNotifRS">
      <HotelReservations>
        ...
      </HotelReservations>
      <Success xsi:nil="true" />
      <Target xsi:nil="true" />
    </OTA_HotelResNotifRS>
    

    TimeStamp and Version became attributes of the root element.