C#:反序列化XML后对象值为null

时间:2016-06-09 16:54:33

标签: c# xml serialization

我正在尝试反序列化API响应中返回的一些XML,但反序列化后我的对象中的所有值都为NULL。

以下是我正在尝试反序列化的响应中的XML。

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

这是我的班级:

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

以下是我用来反序列化的代码:

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

我们将非常感谢任何建议......

3 个答案:

答案 0 :(得分:2)

您提供的xml有2层ctatteta。然而,您的模型只有一层。当然这不会起作用。

您需要更改模型以使布局与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; }
}

答案 1 :(得分:0)

我只知道如何从文件中反序列化元素列表,但这可能有帮助......

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

答案 2 :(得分:0)

如果是complexType,我认为它需要作为类来表示整个元素。创建第二个类(例如“ETAData”)以包含其下的元素。您还需要在trainData类中使用该类型的属性,并将其标记为[XmlElementAttribute]。

编辑:@ Xiaoy312答案更简洁,基本上说明了我所说的内容。