Search code examples
c#xmlxml-deserialization

Xml Deserializer doesn't work for my gpx file


I am trying to deserialize a gpx file into a class, but I am having trouble. I have tried inputting the gpx file text into Xml2CSharp and generating a class that way, but I'm not sure if it is correct (http://xmltocsharp.azurewebsites.net/). When I use debugger, gpx is null. Can someone give me some insight on what I am doing wrong? Thanks.

Gpx Text:

<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.0">
   <trk>
      <trkseg>
         <start lat="37.48996833333333" lon="-122.20991333333335">
            <ele>127.1</ele>
            <time>2017-11-07T02:53:07Z</time>
         </start>
         <trkpt lat="37.48996833333333" lon="-122.20991333333335">
            <ele>127.1</ele>
            <time>2017-11-07T02:53:07Z</time>
         </trkpt>
         <trkpt lat="37.48996833333333" lon="-122.20991333333335">
            <ele>127.1</ele>
            <time>2017-11-07T02:53:07Z</time>
         </trkpt>
      </trkseg>
   </trk>
</gpx>

Current class:

public class XmlSerializeGpx
{
    public Gpx gpx { get; set; }

    public class Start
    {
        public string Ele { get; set; }
        public string Time { get; set; }
        public string Lat { get; set; }
        public string Lon { get; set; }
    }

    public class Trkpt
    {
        public string Ele { get; set; }
        public string Time { get; set; }
        public string Lat { get; set; }
        public string Lon { get; set; }
    }

    public class Trkseg
    {
        public Start Start { get; set; }
        public List<Trkpt> Trkpt { get; set; }
    }

    public class Trk
    {
        public Trkseg Trkseg { get; set; }
    }

    public class Gpx
    {
        public Trk Trk { get; set; }
        public string Xmlns { get; set; }
        public string Version { get; set; }
    }
}

This is my deserializer:

XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "gpx";
xRoot.Namespace = gpxNs.NamespaceName;
xRoot.IsNullable = true;

XmlSerializer xmlSerializer = new XmlSerializer(typeof(XmlSerializeGpx),xRoot);
FileStream fs = new FileStream(file.Path, FileMode.Open);
XmlReader reader = XmlReader.Create(fs);

XmlSerializeGpx gpxObj;

gpxObj = (XmlSerializeGpx)xmlSerializer.Deserialize(reader);

fs.Close();

Solution

  • You need to get the capital and lower case letter correct. See tested code below

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(XmlSerializeGpx.Gpx), "http://www.topografix.com/GPX/1/1");
    
                FileStream fs = new FileStream(FILENAME, FileMode.Open);
                XmlReader reader = XmlReader.Create(fs);
    
                XmlSerializeGpx.Gpx gpxObj = (XmlSerializeGpx.Gpx)xmlSerializer.Deserialize(reader);
    
            }
        }
        public class XmlSerializeGpx
        {
    
            [XmlRoot(ElementName = "start", Namespace = "http://www.topografix.com/GPX/1/1")]
            public class Start
            {
                public double ele { get; set; }
                public DateTime time { get; set; }
                [XmlAttribute("lat")]
                public double lat { get; set; }
                [XmlAttribute("lon")]
                public double lon { get; set; }
            }
    
            [XmlRoot(ElementName = "trkpt", Namespace = "http://www.topografix.com/GPX/1/1")]
            public class Trkpt
            {
                public double ele { get; set; }
                public DateTime time { get; set; }
                [XmlAttribute("lat")]
                public double lat { get; set; }
                [XmlAttribute("lon")]
                public double lon { get; set; }
            }
    
            [XmlRoot(ElementName = "trkseg", Namespace = "http://www.topografix.com/GPX/1/1")]
            public class Trkseg
            {
                [XmlElement("start")]
                public List<Start> start { get; set; }
                [XmlElement("trkpt")]
                public List<Trkpt> trkpt { get; set; }
            }
    
            [XmlRoot(ElementName = "trk", Namespace = "http://www.topografix.com/GPX/1/1")]
            public class Trk
            {
                public Trkseg trkseg { get; set; }
            }
    
            [XmlRoot(ElementName = "gpx", Namespace = "http://www.topografix.com/GPX/1/1")]
            public class Gpx
            {
                public Trk trk { get; set; }
            }
        }
    }