Вопрос

I have a .gpx XML file with the following sample:

<trk>
    <name>Test</name>
    <trkseg>
      <trkpt lon="-84.89032996818423" lat="32.75810896418989">
        <ele>225.0</ele>
        <time>2011-04-02T11:57:48.000Z</time>
        <extensions>
          <gpxtpx:TrackPointExtension>
            <gpxtpx:cad>0</gpxtpx:cad>
          </gpxtpx:TrackPointExtension>
        </extensions>
      </trkpt>
    </trkseg>
</trk>

I'm using Linq to XML to parse this but I'm having a difficult time parsing the extensions section. Here's the code I'm using:

var gpxDoc = LoadFromStream(document);
var gpx = GetGpxNameSpace();
var gpxtpx = XNamespace.Get("gpxtpx");

var tracks = from track in gpxDoc.Descendants(gpx + "trk")
  select new
  {
      Name = DefaultStringValue(track, gpx, "name"),
      Description = DefaultStringValue(track, gpx, "desc"),
      Segments = (from trkSegment in track.Descendants(gpx + "trkseg")
          select new
          {
            TrackSegment = trkSegment,
            Points = (from trackpoint in trkSegment.Descendants(gpx + "trkpt")
              select new
              {
                Lat = Double(trackpoint.Attribute("lat").Value),
                Lng = Double(trackpoint.Attribute("lon").Value),
                Ele = DefaultDoubleValue(trackpoint, gpx, "ele"),
                Time = DefaultDateTimeValue(trackpoint, gpx, "time"),
                Extensions = (
                  from ext in trackpoint.Descendants(gpx + "extensions").Descendants(gpxtpx + "TrackPointExtension")
                  select new
                  {
                    Cad = DefaultIntValue(ext, gpxtpx, "cad")
                  }).SingleOrDefault()
               })
            })
  };

Here's the relevant helper code:

private static double? DefaultIntValue(XContainer element, XNamespace ns, string elementName)
{
    var xElement = element.Element(ns + elementName);
    return xElement != null ? Convert.ToInt32(xElement.Value) : (int?)null;
}

private XNamespace GetGpxNameSpace()
{
    var gpx = XNamespace.Get("http://www.topografix.com/GPX/1/1");
    return gpx;
}

The actual error I'm getting is

The following error occurred: Object reference not set to an instance of an object.

and it bombs on this code:

Extensions = (from ext in trackpoint.Descendants(gpx + "extensions").Descendants(gpxtpx + "TrackPointExtension")
  select new
  {
    Cad = DefaultIntValue(ext, gpxtpx, "cad")
  }).SingleOrDefault();

I just don't know how to fix it.

Это было полезно?

Решение

Since you never declare the namespace (xmlns:gpxtpx="http://www.topografix.com/GPX/1/1") it is never going to match. The xml fragment you provided is not well formed due to the lack of the namespace.

If the fragment posted is snipped from a larger document, consider switching to XML API's rather than string manipulation. If that is the entirety of the XML you receive from an outside system, add it to a root node which you can declare the schema in:

<root xmlns:gpxtpx="http://www.topografix.com/GPX/1/1">
    <!-- put your xml fragment here -->
</root>
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top