DataContract反序列化XML - 同一元素

时间:2016-03-26 22:04:17

标签: c# asp.net asp.net-mvc datacontractserializer datacontract

我在c#ASP.NET环境中工作。我试图将以下XML元素反序列化为c#object / class。该元素深3层。

            <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>

我正在尝试捕获以下对象中的数据,该对象也是3级深度;

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

当我运行代码时,我得到以下异常;

"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."

我已经了解到使用DataContract无法正常工作。有没有办法将“FlightSegment”元素作为列表捕获到RecommendedSegmentFlights中?我已阅读过我需要使用以下任一方法覆盖默认的序列化行为

[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    
}

我是怎么做到的?我想要的只是类中的属性RecommendedSegmentFlights包含FlightSegment元素的列表。我也不介意它是不是推荐部分的孩子。对于RecommendedSegmentFlights属性,我有这个;

public class RecommendedSegmentFlights : List<FlightSegmentStructure> { }

感谢。

2 个答案:

答案 0 :(得分:3)

试试这个......(使用XmlSerializer而不是DataContractSerializer

... Usings

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

Classes ...(使用http://xmltocsharp.azurewebsites.net/从您的XML创建)

[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; }
}

代码....

        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;
        }

将XML保存到与.EXE相同的文件夹中的文件(xml.xml)中......希望有所帮助。

答案 1 :(得分:0)

要反序列化字符串,请尝试此....

... usings

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

Classes ...(使用http://xmltocsharp.azurewebsites.net/从您的XML创建)

[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; }
}

...代码

        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;
        }

要获得FlightSegment列表,请使用此...(将同时适用于两个答案)

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

并添加

using System.Linq;

到代码的顶部.....