0

I am trying to deserialize some XML returned in an API response but all the values in my object are NULL after deserializing.

Below is the XML I am getting in the response that I am trying to deserialize.

<?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>

Here is my class:

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

And here is the code I am using to deserialize:

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!");
                }

Any suggestions would be greatly appreciated...

2
  • You should also include the stacktrace you are getting. Commented Jun 9, 2016 at 17:01
  • 1
    trainData needs an eta type as a property. Those elements nested within eta cannot be deserialized on trainData. Commented Jun 9, 2016 at 17:06

3 Answers 3

2

The xml you provided has 2 layers ctatt and eta. Yet your model has only a single layer. Of course this is not going to work.

You need to change your model to keep the layout the same with the xml :

[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; }
}
Sign up to request clarification or add additional context in comments.

3 Comments

You are missing a property in trainingDataResult for the <errNm> element. Otherwise, this answer seems correct.
@RalphAllanRice Indeed, but it was missing as well in OP's source.
Thanks for all the responses. When I update the model per above I am now getting an error saying that "<ctatt xmlns=' '> is not expected. I ran into this issue earlier and solved it by adding the XmlRoot attribute.
0

I only know how to deserialize a list of elements from a file but maybe it helps...

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

Comments

0

If is a complexType, I believe it need as class to represent that entire element. Create a second class (for example "ETAData") to contain the elements under the . You will also need a property of that type in your trainData class and have it marked with [XmlElementAttribute] also.

EDIT: @Xiaoy312 answer is more concise and basically illustrates what I stated.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.