【问题标题】:DataContract deserialize XML - List of elements and properties in the same elementDataContract 反序列化 XML - 同一元素中的元素和属性列表
【发布时间】:2016-03-26 22:04:16
【问题描述】:

我在 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":"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 元素的列表。我也不介意它是否是RecommendedSegment 的孩子。对于 RecommendedSegmentFlights 属性,我有这个;

public class RecommendedSegmentFlights : List<FlightSegmentStructure> { }

谢谢。

【问题讨论】:

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


【解决方案1】:

试试这个...(使用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) 中。希望对您有所帮助。

【讨论】:

  • 谢谢。这似乎是一个非常简单直接的方法。假设我想反序列化一个 XML 字符串?在 XmlTextReader xmlreader = new XmlTextReader(new System.IO.StringReader(XMLString)); 之后出现错误“XML 文档中存在错误”
【解决方案2】:

要反序列化一个字符串试试这个....

使用....

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;

到代码的顶部.....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    相关资源
    最近更新 更多