使用重复元素

时间:2015-08-06 15:45:10

标签: c# xml serialization

这是VS2012中的C#和针对.NET 4.5的构建

我是XML序列化/反序列化的新手,并试图解决这个问题。我有XML

<?xml version="1.0"?>
<AvailabilityResponse>
  <ApiKey>LZ6c@3O9#tq*BAyX4KGYBsCgZ*HpUDtrB*XI*WGLw</ApiKey>
  <ResellerId>101</ResellerId>
  <SupplierId>1004</SupplierId>
  <ForeignReference>1234567890</ForeignReference>
  <Timestamp>2015-08-06T05:20:49.000Z</Timestamp>
  <RequestStatus>
      <Status>SUCCESS</Status>
  </RequestStatus>
  <TTAsku>dcnt</TTAsku>
  <TourAvailability>
      <TourDate>2015-08-31</TourDate>
      <TourOptions>
          <DepartureTime>07:30 PM</DepartureTime>
      </TourOptions>
      <AvailabilityStatus>
          <Status>AVAILABLE</Status>
      </AvailabilityStatus>
  </TourAvailability>
  <TourAvailability>
      <TourDate>2015-08-31</TourDate>
      <TourOptions>
          <DepartureTime>08:30 PM</DepartureTime>
      </TourOptions>
      <AvailabilityStatus>
          <Status>AVAILABLE</Status>
      </AvailabilityStatus>
  </TourAvailability>
</AvailabilityResponse>

我试图反序列化到这个类结构中:

[Serializable]
public class AvailabilityResponse
{
    public string ApiKey { get; set; }
    public string ResellerId { get; set; }
    public string SupplierId { get; set; }
    public string ForeignReference { get; set; }
    public DateTime Timestamp { get; set; }
    public RequestStatus RequestStatus { get; set; }
    public string TTAsku { get; set; }
    public TourAvailability[] TourAvailability { get; set; }
}

[Serializable]
public class RequestStatus
{
    public string Status { get; set; }
}

[Serializable]
public class TourAvailability
{
    public DateTime TourDate { get; set; }
    public TourOptions TourOptions { get; set; }
    public AvailabilityStatus AvailabilityStatus { get; set; }
}
[Serializable]
public class AvailabilityStatus
{
    public string Status { get; set; }
    public string UnavailabilityReason { get; set; }
}

我这样做:

public static AvailabilityResponse DeserializeAvailabilityResponse(Stream replyStream)
{
    XmlSerializer xmlSr = null;
    XmlReader inreader = null;

    if (replyStream != null)
    {
        XmlTextReader xmlreader = new XmlTextReader(replyStream);
        XmlDocument respXml = new XmlDocument();
        respXml.Load(xmlreader);
        xmlreader.Close();

        xmlSr = DeserializeXmlDoc(respXml, out inreader, typeof(AvailabilityResponse));
    }

    if (xmlSr != null && inreader != null)
    {
        AvailabilityResponse inventory = (AvailabilityResponse)xmlSr.Deserialize(inreader);
        return inventory;
    }
    return null;
}

问题在于,当我检查退回的库存项目时,TourAvailability看起来像这样:
    enter image description here
我希望它像RequestStatus,例如,[+]允许我打开它并查看每个元素。即使我歪曲了它,我也希望至少有一个TourAvailability,而不是零。

我可能在这里遗漏了几件事,但是非常感谢您给予的任何帮助。我有更多这类事情要处理,因为我们的公司正在略微改变方向。

2 个答案:

答案 0 :(得分:1)

只需使用[XmlElement("TourAvailability")]属性,然后您就会看到数组的元素。

public class AvailabilityResponse
{
    public string ApiKey { get; set; }
    public string ResellerId { get; set; }
    public string SupplierId { get; set; }
    public string ForeignReference { get; set; }
    public DateTime Timestamp { get; set; }
    public RequestStatus RequestStatus { get; set; }
    public string TTAsku { get; set; }
    [XmlElement("TourAvailability")]
    public TourAvailability[] TourAvailability { get; set; }
}

顺便说一句:你不需要那些[Serializable]属性

PS:您的反序列化代码可以简化为:

using (var f = File.OpenRead(filename))
{
    XmlSerializer ser = new XmlSerializer(typeof(AvailabilityResponse));
    var resp = (AvailabilityResponse)ser.Deserialize();
}

答案 1 :(得分:0)

试试这个

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            Stream stream = File.Open(FILENAME, FileMode.Open);
            AvailabilityResponse availabilityResponse = DeserializeAvailabilityResponse(stream);
        }
        public static AvailabilityResponse DeserializeAvailabilityResponse(Stream replyStream)
        {
            AvailabilityResponse availabilityResponse = null;
            XmlReader inreader = null;

            if (replyStream != null)
            {
                XmlSerializer xs = new XmlSerializer(typeof(AvailabilityResponse));
                inreader = new XmlTextReader(replyStream);
                availabilityResponse = (AvailabilityResponse)xs.Deserialize(inreader);
                return availabilityResponse;
            }
            else
            {
                return null;
            }
        }

    }
    [XmlRoot("AvailabilityResponse")]
    public class AvailabilityResponse
    {
        [XmlElement("ApiKey")]
        public string ApiKey { get; set; }
        [XmlElement("ResellerId")]
        public int ResellerId { get; set; }
        [XmlElement("SupplierId")]
        public int SupplierId { get; set; }
        [XmlElement("ForeignReference")]
        public string ForeignReference { get; set; }
        [XmlElement("Timestamp")]
        public DateTime Timestamp { get; set; }
        [XmlElement("RequestStatus")]
        public RequestStatus RequestStatus { get; set; }
        [XmlElement("TTAsku")]
        public string TTAsku { get; set; }
        [XmlElement("TourAvailability")]
        public List<TourAvailability> TourAvailability { get; set; }
    }

    [XmlRoot("RequestStatus")]
    public class RequestStatus
    {
        [XmlElement("Status")]
        public string Status { get; set; }
    }

    [XmlRoot("TourAvailability")]
    public class TourAvailability
    {
        [XmlElement("TourDate")]
        public DateTime TourDate { get; set; }
        [XmlElement("TourOptions")]
        public TourOptions TourOptions { get; set; }
        [XmlElement("AvailabilityStatus")]
        public AvailabilityStatus AvailabilityStatus { get; set; }
    }
    [XmlRoot("TourOptions")]
    public class TourOptions
    {
        public DateTime dTime { get; set; }


        [XmlElement("DepartureTime")]
        public string DepartureTime
        {
            get
            {
                return this.dTime.ToString("hh:mm tt");
            }
            set
            {
                this.dTime = DateTime.ParseExact(value, "hh:mm tt", CultureInfo.InvariantCulture);
            }
        }


    }

    [XmlRoot("AvailabilityStatus")]
    public class AvailabilityStatus
    {
        [XmlElement("Status")]
        public string Status { get; set; }
        [XmlElement("UnavailabilityReason")]
        public string UnavailabilityReason { get; set; }
    }
}
​