2015-08-06 6 views
0

Это C# в VS2012 и здание с .NET 4.5Deserialize XML с повторяющимися элементами

Я новичок в XML сериализации/десериализации и пытается понять это. У меня есть XML

<?xml version="1.0"?> 
<AvailabilityResponse> 
    <ApiKey>[email protected]#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
w здесь я ожидал, что это будет похоже на RequestStatus, например, с [+], позволяющим мне открыть его и увидеть каждый элемент. Даже если бы я исказил это, я бы ожидал, что будет хотя бы одна TourAvailability, а не ноль.

Возможно, мне не хватает нескольких вещей, но любая помощь, которую вы можете дать, очень ценится. У меня есть куча таких вещей, с которыми приходится иметь дело, потому что наша компания слегка меняет направление.

+0

я не делаю см. 'ДоступностьStatus'. Какова его структура? –

+1

Вы можете убедиться, что ваши классы структурированы правильно, скопировав xml в буфер обмена, а затем сделайте Edit -> Paste Special -> Paste XML As Classes из visual studio в новый файл класса. – Crowcoder

+0

Добавлен AvailabiltiyStatus в исходном вопросе. – Deverill

ответ

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(); 
} 
+0

Я пробовал это раньше, но он продолжал говорить, что это было недоступно из-за некоторой проблемы с защитой. Это, наверное, мой жуткий код. Я использовал предыдущий XML как классы, как было предложено, и теперь он работает с минимальной настройкой после этого! – Deverill

+0

Спасибо за информацию об атрибутах Serializable и упрощении моего кода. Поскольку это был единственный официальный ответ, и вы помогли обучить меня, и похоже, что ваше решение сработало бы, если бы мой другой код был хорош. Я принимаю этот ответ. Спасибо всем за помощь y'all. – Deverill

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