3

I am working in c# ASP.NET environment. I am trying to deserialise the following XML element into a c# object/class. The element is 3 levels deep.

            <Availability>
                <RecommendedSegment>
                    <Duration>1720</Duration>
                    <FareBasis>Y77OW</FareBasis>
                    <FlightSegment>
                        <DepDate>11 August</DepDate>
                        <DepTime>0830</DepTime>
                        <ArrDate>11 August</ArrDate>
                        <ArrTime>1110</ArrTime>
                        <DepDay>Mon</DepDay>
                        <ArrDay>Mon</ArrDay>
                        <DepAirport>LHR</DepAirport>
                        <DepAirportName>Heathrow</DepAirportName>
                        <DepCityName>London</DepCityName>
                        <ArrAirport>FRA</ArrAirport>
                        <ArrAirportName>Frankfurt Int'l</ArrAirportName>
                        <ArrCityName>Frankfurt</ArrCityName>
                        <DepCountry>United Kingdom</DepCountry>
                        <ArrCountry>Germany</ArrCountry>
                        <Airline>LH</Airline>
                        <AirName>Lufthansa</AirName>
                        <FlightNo>925</FlightNo>
                        <BookingClass>Y</BookingClass>
                        <AirCraftType>32A</AirCraftType>
                        <ETicket>Y</ETicket>
                        <NonStop>0</NonStop>
                        <DepTer>1</DepTer>
                        <ArrTer>1</ArrTer>
                        <AdtFareBasis>Y77OW</AdtFareBasis>
                        <ChdFareBasis>
                        </ChdFareBasis>
                        <InfFareBasis>
                        </InfFareBasis>
                    </FlightSegment>
                    <FlightSegment>
                        <DepDate>11 August</DepDate>
                        <DepTime>1330</DepTime>
                        <ArrDate>12 August</ArrDate>
                        <ArrTime>0100</ArrTime>
                        <DepDay>Mon</DepDay>
                        <ArrDay>Tue</ArrDay>
                        <DepAirport>FRA</DepAirport>
                        <DepAirportName>Frankfurt Int'l</DepAirportName>
                        <DepCityName>Frankfurt</DepCityName>
                        <ArrAirport>BOM</ArrAirport>
                        <ArrAirportName>Bombay</ArrAirportName>
                        <ArrCityName>Mumbai</ArrCityName>
                        <DepCountry>Germany</DepCountry>
                        <ArrCountry>India</ArrCountry>
                        <Airline>LH</Airline>
                        <AirName>Lufthansa</AirName>
                        <FlightNo>756</FlightNo>
                        <BookingClass>Y</BookingClass>
                        <AirCraftType>744</AirCraftType>
                        <ETicket>Y</ETicket>
                        <NonStop>0</NonStop>
                        <DepTer>1</DepTer>
                        <ArrTer>2</ArrTer>
                        <AdtFareBasis>Y77OW</AdtFareBasis>
                        <ChdFareBasis>
                        </ChdFareBasis>
                        <InfFareBasis>
                        </InfFareBasis>
                    </FlightSegment>
                    <FlightSegment>
                        <DepDate>12 August</DepDate>
                        <DepTime>0515</DepTime>
                        <ArrDate>12 August</ArrDate>
                        <ArrTime>0620</ArrTime>
                        <DepDay>Tue</DepDay>
                        <ArrDay>Tue</ArrDay>
                        <DepAirport>BOM</DepAirport>
                        <DepAirportName>Bombay</DepAirportName>
                        <DepCityName>Mumbai</DepCityName>
                        <ArrAirport>GOI</ArrAirport>
                        <ArrAirportName>Dabolim</ArrAirportName>
                        <ArrCityName>Goa</ArrCityName>
                        <DepCountry>India</DepCountry>
                        <ArrCountry>India</ArrCountry>
                        <Airline>AI</Airline>
                        <AirName>Air India</AirName>
                        <FlightNo>984</FlightNo>
                        <BookingClass>Y</BookingClass>
                        <AirCraftType>321</AirCraftType>
                        <ETicket>Y</ETicket>
                        <NonStop>0</NonStop>
                        <DepTer>2</DepTer>
                        <ArrTer>
                        </ArrTer>
                        <AdtFareBasis>Y</AdtFareBasis>
                        <ChdFareBasis>
                        </ChdFareBasis>
                        <InfFareBasis>
                        </InfFareBasis>
                    </FlightSegment>
                    <DepAirport>LHR</DepAirport>
                    <DepCity>LON</DepCity>
                    <DepCountry>GB</DepCountry>
                    <DepZone>1</DepZone>
                    <ArrAirport>GOI</ArrAirport>
                    <ArrCity>GOI</ArrCity>
                    <ArrCountry>IN</ArrCountry>
                    <ArrZone>5</ArrZone>
                </RecommendedSegment>
            </Availability>

I am trying to capture the data in the following object which is also 3 levels deep;

[DataContract(Name = "Availability")]
    public class Availability
    {
        [DataMember(Name = "RecommendedSegment", Order = 0)]
        public RecommendedSegment RecommendedSegment;
        [DataMember(Name = "RecommendedSegment", Order = 1)]
        public RecommendedSegmentFlights RecommendedSegmentFlights;
    }

When I run the code I get the following exception;

"ExceptionMessage":"Type 'Availability' contains two members 'RecommendedSegment' 'and 'RecommendedSegmentFlights' with the same data member name 'RecommendedSegment'. Multiple members with the same name in one type are not supported. Consider changing one of the member names using DataMemberAttribute attribute."

I have learnt that won't work using DataContract. Is there a way to capture the "FlightSegment" elements into the RecommendedSegmentFlights as a list? I have read I need to override the default serialisation behaviour by using either of the following

[OnDeserialized]
    void OnDeserialized(StreamingContext c)
    {
      if (MyCustonObj == null)
      {
        MyCustonObj = new MyCustomClass();
        MyCustonObj.MyStrData = "Overridden in serialization";
      }
    }
[OnDeserializing]
void OnDeserializing(StreamingContext c)
{
  if (MyCustonObj == null)
  {
    MyCustonObj = new MyCustomClass();
    MyCustonObj.MyStrData = "Overridden in  deserializing";
  }
}

[OnSerialized]
void OnSerialized(StreamingContext c)
{
   // if you wan to  do somehing when serialized here or just remove them

}

[OnSerializing]
void OnSerializing(StreamingContext c)
{
   // if you wan to  do somehing during serializing here or just remove them    
}

How do I that? All I want is the property RecommendedSegmentFlights in the class to contain a list of FlightSegment elements. I also don't mind if it is a child of RecommendedSegment. For the RecommendedSegmentFlights property I have this;

public class RecommendedSegmentFlights : List<FlightSegmentStructure> { }

Thanks.

  • *Must* you use `DataContractSerializer`? Unlike `XmlSerializer`, it [does not allow a list to be serialized without the outer container element](https://stackoverflow.com/questions/8591045/data-contract-serializer-how-to-omit-the-outer-element-of-a-collection). – dbc Mar 26 '16 at 23:12
  • @user5500750, we hope that your issue has been resolved. May I suggest some further reading http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work... regards... – Monty Mar 27 '16 at 00:34
  • Is there a solution using DataContracts? Monty's answer seems to work but I am having problems deserializing the XML from string. –  Mar 27 '16 at 00:58
  • @user5500750 see my new answer to deserialize an XML string..... – Monty Mar 27 '16 at 10:18

2 Answers2

3

Try this... (uses XmlSerializer rather than DataContractSerializer)

Usings...

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;

Classes...(created from your XML using http://xmltocsharp.azurewebsites.net/)

[XmlRoot(ElementName = "FlightSegment")]
public class FlightSegment
{
    [XmlElement(ElementName = "DepDate")]
    public string DepDate { get; set; }
    [XmlElement(ElementName = "DepTime")]
    public string DepTime { get; set; }
    [XmlElement(ElementName = "ArrDate")]
    public string ArrDate { get; set; }
    [XmlElement(ElementName = "ArrTime")]
    public string ArrTime { get; set; }
    [XmlElement(ElementName = "DepDay")]
    public string DepDay { get; set; }
    [XmlElement(ElementName = "ArrDay")]
    public string ArrDay { get; set; }
    [XmlElement(ElementName = "DepAirport")]
    public string DepAirport { get; set; }
    [XmlElement(ElementName = "DepAirportName")]
    public string DepAirportName { get; set; }
    [XmlElement(ElementName = "DepCityName")]
    public string DepCityName { get; set; }
    [XmlElement(ElementName = "ArrAirport")]
    public string ArrAirport { get; set; }
    [XmlElement(ElementName = "ArrAirportName")]
    public string ArrAirportName { get; set; }
    [XmlElement(ElementName = "ArrCityName")]
    public string ArrCityName { get; set; }
    [XmlElement(ElementName = "DepCountry")]
    public string DepCountry { get; set; }
    [XmlElement(ElementName = "ArrCountry")]
    public string ArrCountry { get; set; }
    [XmlElement(ElementName = "Airline")]
    public string Airline { get; set; }
    [XmlElement(ElementName = "AirName")]
    public string AirName { get; set; }
    [XmlElement(ElementName = "FlightNo")]
    public string FlightNo { get; set; }
    [XmlElement(ElementName = "BookingClass")]
    public string BookingClass { get; set; }
    [XmlElement(ElementName = "AirCraftType")]
    public string AirCraftType { get; set; }
    [XmlElement(ElementName = "ETicket")]
    public string ETicket { get; set; }
    [XmlElement(ElementName = "NonStop")]
    public string NonStop { get; set; }
    [XmlElement(ElementName = "DepTer")]
    public string DepTer { get; set; }
    [XmlElement(ElementName = "ArrTer")]
    public string ArrTer { get; set; }
    [XmlElement(ElementName = "AdtFareBasis")]
    public string AdtFareBasis { get; set; }
    [XmlElement(ElementName = "ChdFareBasis")]
    public string ChdFareBasis { get; set; }
    [XmlElement(ElementName = "InfFareBasis")]
    public string InfFareBasis { get; set; }
}

[XmlRoot(ElementName = "RecommendedSegment")]
public class RecommendedSegment
{
    [XmlElement(ElementName = "Duration")]
    public string Duration { get; set; }
    [XmlElement(ElementName = "FareBasis")]
    public string FareBasis { get; set; }
    [XmlElement(ElementName = "FlightSegment")]
    public List<FlightSegment> FlightSegment { get; set; }
    [XmlElement(ElementName = "DepAirport")]
    public string DepAirport { get; set; }
    [XmlElement(ElementName = "DepCity")]
    public string DepCity { get; set; }
    [XmlElement(ElementName = "DepCountry")]
    public string DepCountry { get; set; }
    [XmlElement(ElementName = "DepZone")]
    public string DepZone { get; set; }
    [XmlElement(ElementName = "ArrAirport")]
    public string ArrAirport { get; set; }
    [XmlElement(ElementName = "ArrCity")]
    public string ArrCity { get; set; }
    [XmlElement(ElementName = "ArrCountry")]
    public string ArrCountry { get; set; }
    [XmlElement(ElementName = "ArrZone")]
    public string ArrZone { get; set; }
}

[XmlRoot(ElementName = "Availability")]
public class Availability
{
    [XmlElement(ElementName = "RecommendedSegment")]
    public RecommendedSegment RecommendedSegment { get; set; }
}

Code....

        try
        {
            Availability deserializedXML = new Availability();
            // Deserialize to object
            XmlSerializer serializer = new XmlSerializer(typeof(Availability));
            using (FileStream stream = File.OpenRead(@"xml.xml"))
            {
                deserializedXML = (Availability)serializer.Deserialize(stream);
            } // Put a break-point here, then mouse-over deserializedXML
        }
        catch (Exception)
        {

            throw;
        }

Save your XML to a file (xml.xml) in the same folder as your .EXE.... Hope that helps.

Guru Stron
  • 102,774
  • 10
  • 95
  • 132
Monty
  • 1,534
  • 2
  • 10
  • 12
  • Thanks. This seems like a very simple and straight forward. Suppose I wanted to deserialize an XML string? I am getting an error "There is an error in XML document" after XmlTextReader xmlreader = new XmlTextReader(new System.IO.StringReader(XMLString)); –  Mar 27 '16 at 00:59
0

To Deserialize a string try this....

usings....

using System;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

Classes...(created from your XML using http://xmltocsharp.azurewebsites.net/)

[XmlRoot(ElementName = "FlightSegment")]
public class FlightSegment
{
    [XmlElement(ElementName = "DepDate")]
    public string DepDate { get; set; }
    [XmlElement(ElementName = "DepTime")]
    public string DepTime { get; set; }
    [XmlElement(ElementName = "ArrDate")]
    public string ArrDate { get; set; }
    [XmlElement(ElementName = "ArrTime")]
    public string ArrTime { get; set; }
    [XmlElement(ElementName = "DepDay")]
    public string DepDay { get; set; }
    [XmlElement(ElementName = "ArrDay")]
    public string ArrDay { get; set; }
    [XmlElement(ElementName = "DepAirport")]
    public string DepAirport { get; set; }
    [XmlElement(ElementName = "DepAirportName")]
    public string DepAirportName { get; set; }
    [XmlElement(ElementName = "DepCityName")]
    public string DepCityName { get; set; }
    [XmlElement(ElementName = "ArrAirport")]
    public string ArrAirport { get; set; }
    [XmlElement(ElementName = "ArrAirportName")]
    public string ArrAirportName { get; set; }
    [XmlElement(ElementName = "ArrCityName")]
    public string ArrCityName { get; set; }
    [XmlElement(ElementName = "DepCountry")]
    public string DepCountry { get; set; }
    [XmlElement(ElementName = "ArrCountry")]
    public string ArrCountry { get; set; }
    [XmlElement(ElementName = "Airline")]
    public string Airline { get; set; }
    [XmlElement(ElementName = "AirName")]
    public string AirName { get; set; }
    [XmlElement(ElementName = "FlightNo")]
    public string FlightNo { get; set; }
    [XmlElement(ElementName = "BookingClass")]
    public string BookingClass { get; set; }
    [XmlElement(ElementName = "AirCraftType")]
    public string AirCraftType { get; set; }
    [XmlElement(ElementName = "ETicket")]
    public string ETicket { get; set; }
    [XmlElement(ElementName = "NonStop")]
    public string NonStop { get; set; }
    [XmlElement(ElementName = "DepTer")]
    public string DepTer { get; set; }
    [XmlElement(ElementName = "ArrTer")]
    public string ArrTer { get; set; }
    [XmlElement(ElementName = "AdtFareBasis")]
    public string AdtFareBasis { get; set; }
    [XmlElement(ElementName = "ChdFareBasis")]
    public string ChdFareBasis { get; set; }
    [XmlElement(ElementName = "InfFareBasis")]
    public string InfFareBasis { get; set; }
}

[XmlRoot(ElementName = "RecommendedSegment")]
public class RecommendedSegment
{
    [XmlElement(ElementName = "Duration")]
    public string Duration { get; set; }
    [XmlElement(ElementName = "FareBasis")]
    public string FareBasis { get; set; }
    [XmlElement(ElementName = "FlightSegment")]
    public List<FlightSegment> FlightSegment { get; set; }
    [XmlElement(ElementName = "DepAirport")]
    public string DepAirport { get; set; }
    [XmlElement(ElementName = "DepCity")]
    public string DepCity { get; set; }
    [XmlElement(ElementName = "DepCountry")]
    public string DepCountry { get; set; }
    [XmlElement(ElementName = "DepZone")]
    public string DepZone { get; set; }
    [XmlElement(ElementName = "ArrAirport")]
    public string ArrAirport { get; set; }
    [XmlElement(ElementName = "ArrCity")]
    public string ArrCity { get; set; }
    [XmlElement(ElementName = "ArrCountry")]
    public string ArrCountry { get; set; }
    [XmlElement(ElementName = "ArrZone")]
    public string ArrZone { get; set; }
}

[XmlRoot(ElementName = "Availability")]
public class Availability
{
    [XmlElement(ElementName = "RecommendedSegment")]
    public RecommendedSegment RecommendedSegment { get; set; }
}

Code...

        string strXML = @"<Availability>
            <RecommendedSegment>
                <Duration>1720</Duration>
                <FareBasis>Y77OW</FareBasis>
                <FlightSegment>
                    <DepDate>11 August</DepDate>
                    <DepTime>0830</DepTime>
                    <ArrDate>11 August</ArrDate>
                    <ArrTime>1110</ArrTime>
                    <DepDay>Mon</DepDay>
                    <ArrDay>Mon</ArrDay>
                    <DepAirport>LHR</DepAirport>
                    <DepAirportName>Heathrow</DepAirportName>
                    <DepCityName>London</DepCityName>
                    <ArrAirport>FRA</ArrAirport>
                    <ArrAirportName>Frankfurt Int'l</ArrAirportName>
                    <ArrCityName>Frankfurt</ArrCityName>
                    <DepCountry>United Kingdom</DepCountry>
                    <ArrCountry>Germany</ArrCountry>
                    <Airline>LH</Airline>
                    <AirName>Lufthansa</AirName>
                    <FlightNo>925</FlightNo>
                    <BookingClass>Y</BookingClass>
                    <AirCraftType>32A</AirCraftType>
                    <ETicket>Y</ETicket>
                    <NonStop>0</NonStop>
                    <DepTer>1</DepTer>
                    <ArrTer>1</ArrTer>
                    <AdtFareBasis>Y77OW</AdtFareBasis>
                    <ChdFareBasis>
                    </ChdFareBasis>
                    <InfFareBasis>
                    </InfFareBasis>
                </FlightSegment>
                <FlightSegment>
                    <DepDate>11 August</DepDate>
                    <DepTime>1330</DepTime>
                    <ArrDate>12 August</ArrDate>
                    <ArrTime>0100</ArrTime>
                    <DepDay>Mon</DepDay>
                    <ArrDay>Tue</ArrDay>
                    <DepAirport>FRA</DepAirport>
                    <DepAirportName>Frankfurt Int'l</DepAirportName>
                    <DepCityName>Frankfurt</DepCityName>
                    <ArrAirport>BOM</ArrAirport>
                    <ArrAirportName>Bombay</ArrAirportName>
                    <ArrCityName>Mumbai</ArrCityName>
                    <DepCountry>Germany</DepCountry>
                    <ArrCountry>India</ArrCountry>
                    <Airline>LH</Airline>
                    <AirName>Lufthansa</AirName>
                    <FlightNo>756</FlightNo>
                    <BookingClass>Y</BookingClass>
                    <AirCraftType>744</AirCraftType>
                    <ETicket>Y</ETicket>
                    <NonStop>0</NonStop>
                    <DepTer>1</DepTer>
                    <ArrTer>2</ArrTer>
                    <AdtFareBasis>Y77OW</AdtFareBasis>
                    <ChdFareBasis>
                    </ChdFareBasis>
                    <InfFareBasis>
                    </InfFareBasis>
                </FlightSegment>
                <FlightSegment>
                    <DepDate>12 August</DepDate>
                    <DepTime>0515</DepTime>
                    <ArrDate>12 August</ArrDate>
                    <ArrTime>0620</ArrTime>
                    <DepDay>Tue</DepDay>
                    <ArrDay>Tue</ArrDay>
                    <DepAirport>BOM</DepAirport>
                    <DepAirportName>Bombay</DepAirportName>
                    <DepCityName>Mumbai</DepCityName>
                    <ArrAirport>GOI</ArrAirport>
                    <ArrAirportName>Dabolim</ArrAirportName>
                    <ArrCityName>Goa</ArrCityName>
                    <DepCountry>India</DepCountry>
                    <ArrCountry>India</ArrCountry>
                    <Airline>AI</Airline>
                    <AirName>Air India</AirName>
                    <FlightNo>984</FlightNo>
                    <BookingClass>Y</BookingClass>
                    <AirCraftType>321</AirCraftType>
                    <ETicket>Y</ETicket>
                    <NonStop>0</NonStop>
                    <DepTer>2</DepTer>
                    <ArrTer>
                    </ArrTer>
                    <AdtFareBasis>Y</AdtFareBasis>
                    <ChdFareBasis>
                    </ChdFareBasis>
                    <InfFareBasis>
                    </InfFareBasis>
                </FlightSegment>
                <DepAirport>LHR</DepAirport>
                <DepCity>LON</DepCity>
                <DepCountry>GB</DepCountry>
                <DepZone>1</DepZone>
                <ArrAirport>GOI</ArrAirport>
                <ArrCity>GOI</ArrCity>
                <ArrCountry>IN</ArrCountry>
                <ArrZone>5</ArrZone>
            </RecommendedSegment>
        </Availability>";

        byte[] bufXML = ASCIIEncoding.UTF8.GetBytes(strXML);
        MemoryStream ms1 = new MemoryStream(bufXML);

        // Deserialize to object
        XmlSerializer serializer = new XmlSerializer(typeof(Availability));
        try
        {
            using (XmlReader reader = new XmlTextReader(ms1))
            {
                Availability deserializedXML = (Availability)serializer.Deserialize(reader);

            }// put a break point here and mouse-over Label1Text and Label2Text ….
        }
        catch (Exception ex)
        {
            throw;
        }

And to get a list of FlightSegment use this... (will work for both answers)

List<FlightSegment> FlightSegmentList = (from fs in deserializedXML.RecommendedSegment.FlightSegment select fs).ToList();

and add

using System.Linq;

to the top of your code.....

Monty
  • 1,534
  • 2
  • 10
  • 12