DataContract 反序列化 XML - 同一元素中的元素和属性列表

问题描述 投票:0回答:2

我在 c# ASP.NET 环境中工作。我正在尝试将以下 XML 元素反序列化为 C# 对象/类。该元素有 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":"类型'Availability'包含两个具有相同数据成员名称'RecommendedSegment'的成员'RecommendedSegment''和'RecommendedSegmentFlights'。不支持一种类型中具有相同名称的多个成员。请考虑更改其中一个成员使用 DataMemberAttribute 属性命名。”

我了解到使用 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 元素的列表。我也不介意它是否是RecommendedSegment 的子级。对于RecommendedSegmentFlights 属性,我有这个;

public class RecommendedSegmentFlights : List<FlightSegmentStructure> { }
c# asp.net asp.net-mvc datacontractserializer datacontract
2个回答
3
投票

试试这个...(使用

XmlSerializer
而不是
DataContractSerializer

用途...

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

类...(使用 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)...希望有帮助。


0
投票

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

用途....

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

类...(使用 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;

到代码顶部......

© www.soinside.com 2019 - 2024. All rights reserved.