I have a C# program that reads a gpx file, I place every element in a variable and at the end I put all thos element in an object. for al these elements I have functions, so each function reads a tag, I do that with this if statement:
public double GetEle(XmlReader reader)
{
if ((reader.NodeType == XmlNodeType.Element) && (reader.Name == "ele"))
{
MessageBox.Show(Convert.ToString(reader.ReadElementContentAsDouble()));
double value = reader.ReadElementContentAsDouble();
return Math.Round(value, 2);
}
return 0;
}
the problem is that my program never goes into that if statement (my messageBox doesn't pop up) however if I place that if statement inside this loop ↓ . Then my program goes into all my if statement.
while (reader.Read())
{}
My problem is that I use while (reader.Read()) in the function that calls my GetEle() function. So I don't want to loop throught my GetEle() function, only run it one time:
public List<GPXDataObject> Extract(string path)
{
if (path == String.Empty)
{
throw new ArgumentOutOfRangeException("path");
}
if (path == null)
{
throw new ArgumentNullException("path");
}
List<GPXDataObject> gpxDataList = new List<GPXDataObject>();
using (XmlReader reader = XmlReader.Create(path))
{
while (reader.Read())
{
List<double> coordinates = Coordinates(reader);
double lat = coordinates[0];
double lon = coordinates[1];
double ele = GetEle(reader);
DateTime date = GetDate(reader);
float speed = GetSpeed(reader);
float azimuth = GetAzimuth(reader);
GPXDataObject gpxDataObject = new GPXDataObject(lat, lon, ele, date, speed, azimuth);
gpxDataList.Add(gpxDataObject);
}
reader.Close();
}
return gpxDataList;
}
I have this problem in all my functions, if I use while(reader.read()) the function works, but loops throught my whole gpx file and returns the last element. If I don't include the while loop my program never goes into my if statement.
Here is a sample of my xml data:
<trk>
<trkseg>
<trkpt lat="47.021897" lon="9.965247">
<ele>811.90</ele>
<time>2015-02-18T07:17:25.01Z</time>
<extensions>
<gte:gps speed="2.1" azimuth="42.9"/>
</extensions>
</trkpt>
<trkpt lat="47.021896" lon="9.965999">
<ele>812.19</ele>
<time>2015-02-18T07:17:25.21Z</time>
<extensions>
<gte:gps speed="2.0" azimuth="44.3"/>
</extensions>
</trkpt>
<trkpt lat="47.021890" lon="9.965241">
<ele>812.53</ele>
<time>2015-02-18T07:17:25.41Z</time>
<extensions>
<gte:gps speed="1.5" azimuth="48.0"/>
</extensions>
</trkpt>
<trkpt lat="47.021885" lon="9.965238">
<ele>812.49</ele>
<time>2015-02-18T07:17:25.61Z</time>
<extensions>
<gte:gps speed="1.2" azimuth="58.7"/>
</extensions>
</trkpt>
</trkseg>
I hope I explained my problem clear enough and someone will take the time to read through it and help me. :D
XmlReader
is forward-only reading, and it only advances when you call .Read()
- so here's what your program is currently doing (assuming the Coordinates
constructor that takes an XmlReader
is meant to parse the trkpt
element):
GPXDataObject
.Here's more along the lines of what you probably want:
using (XmlReader reader = XmlReader.Create(path))
{
reader.MoveToContent();
while (reader.ReadToFollowing("trkpt")) // advance the reader to the next trkpt element
{
List<double> coordinates = Coordinates(reader);
double lat = coordinates[0];
double lon = coordinates[1];
reader.ReadToFollowing("ele"); // reader.Read() might work here, depending on what state Coordinates left the reader in
double ele = GetEle(reader);
reader.ReadToFollowing("time");
DateTime date = GetDate(reader);
reader.ReadToFollowing("extensions"); // note: it's not clear what GetSpeed and GetAzimuth need - do they expect the reader to be on the extensions element or the gte:gps element?
float speed = GetSpeed(reader);
float azimuth = GetAzimuth(reader);
GPXDataObject gpxDataObject = new GPXDataObject(lat, lon, ele, date, speed, azimuth);
gpxDataList.Add(gpxDataObject);
}
}
That should at least get you started.