2016-06-09 10 views
0

Ich versuche, einige in einer API-Antwort zurückgegebene XML zu deserialisieren, aber alle Werte in meinem Objekt sind nach der Deserialisierung NULL.C#: Objektwerte null nach dem Deserialisieren von XML

Unten ist das XML, das ich in der Antwort bekomme, die ich versuche zu deserialisieren.

<?xml version="1.0" encoding="utf-8"?> 
<ctatt> 
    <tmst>20160609 11:50:03</tmst> 
    <errCd>0</errCd> 
    <errNm /> 
    <eta> 
     <staId>41300</staId> 
     <stpId>30252</stpId> 
     <staNm>Loyola</staNm> 
     <stpDe>Service toward 95th/Dan Ryan</stpDe> 
     <rn>803</rn> 
     <rt>Red</rt> 
     <destSt>30089</destSt> 
     <destNm>95th/Dan Ryan</destNm> 
     <trDr>5</trDr> 
     <prdt>20160609 11:48:45</prdt> 
     <arrT>20160609 11:51:45</arrT> 
     <isApp>0</isApp> 
     <isSch>0</isSch> 
     <isDly>0</isDly> 
     <isFlt>0</isFlt> 
     <flags /> 
     <lat>42.01906</lat> 
     <lon>-87.67289</lon> 
     <heading>130</heading> 
    </eta> 
</ctatt> 

Hier ist meine Klasse:

[Serializable, XmlRoot("ctatt")] 
     public class trainData 
     { 
      [XmlElement(ElementName ="tmst")] 
      public string timeStamp { get; set; } 

      [XmlElement(ElementName = "errCd")] 
      public byte errorCode { get; set; } 

      [XmlElement(ElementName = "staId")] 
      public ushort stationId { get; set; } 

      [XmlElement(ElementName = "stpId")] 
      public ushort stopId { get; set; } 

      [XmlElement(ElementName = "staNm")] 
      public string stationName { get; set; } 

      [XmlElement(ElementName = "stpDe")] 
      public string stopDesc { get; set; } 

      [XmlElement(ElementName = "rn")] 
      public ushort runNum { get; set; } 

      [XmlElement(ElementName = "rt")] 
      public string routeName { get; set; } 

      [XmlElement(ElementName = "destSt")] 
      public ushort destStation { get; set; } 

      [XmlElement(ElementName = "destNm")] 
      public string destName { get; set; } 

      [XmlElement(ElementName = "trDr")] 
      public byte trainDir { get; set; } 

      [XmlElement(ElementName = "prdt")] 
      public string prdTime {get; set;} 

      [XmlElement(ElementName = "arrT")] 
      public string arrTime { get; set; } 

      [XmlElement(ElementName = "isApp")] 
      public ushort isApp { get; set; } 

      [XmlElement(ElementName = "isSch")] 
      public ushort isSch { get; set; } 

      [XmlElement(ElementName = "isDly")] 
      public ushort isDly { get; set; } 

      [XmlElement(ElementName = "isFlt")] 
      public ushort isFlt { get; set; } 

      [XmlElement(ElementName = "flags")] 
      public string flags { get; set; } 

      [XmlElement(ElementName = "lat")] 
      public double lat { get; set; } 

      [XmlElement(ElementName = "lon")] 
      public double lon { get; set; } 

      [XmlElement(ElementName = "heading")] 
      public ushort heading { get; set; } 
     } 

Und hier ist der Code, den ich deserialisieren bin mit:

var response = await client.GetAsync(urlParameters); 
       if (response.IsSuccessStatusCode) 
       { 
        var xml = await response.Content.ReadAsStringAsync(); 
        XmlSerializer deserializer = new XmlSerializer(typeof(trainData)); 
        using (StringReader reader = new StringReader(xml)) 
        { 
         using (XmlReader xr = XmlReader.Create(reader)) 
         { 
          trainData result = (trainData)deserializer.Deserialize(xr); 
          Console.WriteLine("Station Name: {0}\nRoute Name: {1}\nArrival Time: {2}", result.stationName, result.routeName, result.arrTime); 
         } 
        } 
       } 
       else 
       { 
        Console.WriteLine("There was an error!"); 
       } 

Irgendwelche Vorschläge wäre sehr dankbar ...

+0

Sie sollten auch den StackTrace enthalten, den Sie erhalten. –

+1

'trainData' benötigt einen' eta' Typ als Eigenschaft. Diese Elemente, die in 'eta' verschachtelt sind, können nicht auf 'trainData' deserialisiert werden. – Crowcoder

Antwort

2

Die XML-Datei, die Sie zur Verfügung gestellt haben, enthält 2 Ebenen ctatt und eta. Ihr Modell hat jedoch nur eine einzige Ebene. Natürlich wird das nicht funktionieren.

Sie benötigen Modell zu ändern, das Layout, das gleiche mit dem xml zu halten:

[Serializable, XmlRoot("ctatt")] 
public class trainDataResult 
{ 
    [XmlElement(ElementName ="tmst")] 
    public string timeStamp { get; set; } 

    [XmlElement(ElementName = "errCd")] 
    public byte errorCode { get; set; } 

    // uncomment next lines to include `errNm` 
    //[XmlElement(ElementName = "errNm")] 
    //public string errorName { get; set; } 

    [XmlElement(ElementName = "eta")] 
    public TrainData eta { get; set; } 
} 

public class TrainData 
{ 
    [XmlElement(ElementName = "staId")] 
    public ushort stationId { get; set; } 

    [XmlElement(ElementName = "stpId")] 
    public ushort stopId { get; set; } 

    [XmlElement(ElementName = "staNm")] 
    public string stationName { get; set; } 

    [XmlElement(ElementName = "stpDe")] 
    public string stopDesc { get; set; } 

    [XmlElement(ElementName = "rn")] 
    public ushort runNum { get; set; } 

    [XmlElement(ElementName = "rt")] 
    public string routeName { get; set; } 

    [XmlElement(ElementName = "destSt")] 
    public ushort destStation { get; set; } 

    [XmlElement(ElementName = "destNm")] 
    public string destName { get; set; } 

    [XmlElement(ElementName = "trDr")] 
    public byte trainDir { get; set; } 

    [XmlElement(ElementName = "prdt")] 
    public string prdTime {get; set;} 

    [XmlElement(ElementName = "arrT")] 
    public string arrTime { get; set; } 

    [XmlElement(ElementName = "isApp")] 
    public ushort isApp { get; set; } 

    [XmlElement(ElementName = "isSch")] 
    public ushort isSch { get; set; } 

    [XmlElement(ElementName = "isDly")] 
    public ushort isDly { get; set; } 

    [XmlElement(ElementName = "isFlt")] 
    public ushort isFlt { get; set; } 

    [XmlElement(ElementName = "flags")] 
    public string flags { get; set; } 

    [XmlElement(ElementName = "lat")] 
    public double lat { get; set; } 

    [XmlElement(ElementName = "lon")] 
    public double lon { get; set; } 

    [XmlElement(ElementName = "heading")] 
    public ushort heading { get; set; } 
} 
+0

Sie fehlen eine Eigenschaft in trainingDataResult für das Element . Ansonsten scheint diese Antwort korrekt zu sein. –

+0

@RalphAllanRice Tatsächlich, aber es fehlte auch in der Quelle von OP. – Xiaoy312

+0

Danke für alle Antworten. Wenn ich das oben genannte Modell aktualisiere, bekomme ich jetzt einen Fehler, der besagt, dass " nicht erwartet wird. Ich habe dieses Problem früher gelöst und es durch Hinzufügen des XmlRoot-Attributs gelöst. – orajestad9

0

ich nur wissen, wie eine Liste von Elementen aus einer Datei deserialisieren, aber vielleicht hilft es ...

List<trainData> result = new List<trainData>; 
    using (FileStream stream = new FileStream(Filepath,Filemode.Open) 
{ 
XmlSerializer Serializer =new XmlSerializer(typeof(List<trainData>)); 
result = Serializer.Deserialize(stream); 
} 
+0

Die angegebene XML-Datei funktioniert nicht irgend etwas Array-ähnliches enthalten ... – Xiaoy312

0

Wenn es ein complexType ist, glaube ich, dass es als Klasse benötigt, um das gesamte Element darzustellen. Erstellen Sie eine zweite Klasse (z. B. "ETAData"), die die Elemente unter dem Namen enthält. Sie benötigen außerdem eine Eigenschaft dieses Typs in Ihrer trainData-Klasse und lassen sie ebenfalls mit [XmlElementAttribute] kennzeichnen.

EDIT: @ Xiaoy312 Antwort ist prägnanter und im Grunde illustriert, was ich sagte.

Verwandte Themen