Open brendanashworth opened 6 years ago
As a first step, I think it'll make most sense to implement lax validation and just ignore the <extensions>
tag with all children. I was going to suggest to make read
take some setting struct with an option lax
(or strict
), but now when I think of it, there's shouldn't be much need for that "strict" mode that fails when it encounters <extensions>
, so it would be OK to simply ignore it unconditionally.
I'll put a PR for that. Then I'll work a bit with my tracks to get a better grasp of Rust and rust-gpx while we can think about a good way to support third-party extensions. I assume that we want to make it in such a way that support for various extensions can be implemented without modifying rust-gpx (and e.g. passed as parameter, or implicitly via some trait).
@zudov ignoring <extensions>
by default sounds like a good first step to me.
One of the struggles we might face is with xml-rs, perhaps there's another library more cut out for the problem. Or, even, we could just pass back the data as some sort of callback or something and let the API consumer write their own decoding program.
It seems like the first step is now implemented, i.e. skipping any <extensions>
elements at various nesting levels, including the <trkpt>
and <trk>
levels. However, gpx files created/edited in QMapShack (and possibly QLandkarteGT) have an <extensions>
element as a direct child node of the <gpx>
root element. That leads to an InvalidChildElement("extensions", "gpx")
error. So unless this violates the GPX standard in some way (or maybe even then), it might be a good idea to skip the element on that nesting level, too?
Wouldn't the best route be to use the extra schemas provided at root to parse the extensions.
From The Docs: You can add extend GPX by adding your own elements from another schema here.
Given the example below with Garmin Extensions
Getting this
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
And using the xsi:schemaLocation=
map.
You then query this file.
http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd
Which contains the schema for the extentions that start with gpxx
<extensions><gpxx:TrackExtension><gpxx:DisplayColor>DarkGray</gpxx:DisplayColor></gpxx:TrackExtension>
This seems to be the to spec approach. Though I'm not sure how rust would be able to handle the scenario. And how that would interact with typing
The referenced file.
<?xml version="1.0"?>
<gpx version="1.1"
creator="Viking 1.10 -- http://viking.sf.net/"
xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v2" xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v2 http://www.garmin.com/xmlschemas/TrackPointExtensionv2.xsd http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd">
<wpt lat="40.71488" lon="-74.011422">
<name>001</name>
</wpt>
<trk>
<name>Trace</name>
<extensions><gpxx:TrackExtension><gpxx:DisplayColor>DarkGray</gpxx:DisplayColor></gpxx:TrackExtension></extensions>
<trkseg>
<trkpt lat="40.71631157206666" lon="-74.01103529632569">
</trkpt>
<trkpt lat="40.7154983764096" lon="-74.00927576721192">
</trkpt>
<trkpt lat="40.71435988580241" lon="-74.01021990478516">
</trkpt>
<trkpt lat="40.7139370129041" lon="-74.00888952911377">
</trkpt>
<trkpt lat="40.71149730912246" lon="-74.01047739685059">
</trkpt>
</trkseg>
</trk>
<rte>
<name>Route</name>
<extensions><gpxx:TrackExtension><gpxx:DisplayColor>Red</gpxx:DisplayColor></gpxx:TrackExtension></extensions>
</rte>
</gpx>
Personally, I think the previous pull request for this (simply hand the raw XML string over to the application) was not the worst approach.
Basically, if the gpx crate wants to do anything more than "allow the application to access the raw XML string" for extensions, it would have to expose functionality from the XML parsing crate used by this crate. So just pass on any XML parsing events inside those
Maybe some common extensions can be supported and parsed by the gpx crate itself. However, I don't think there's a general solution for this issue that supports all extensions and is "better" than a generic XML parser. And allowing to access the raw extension XML might very well be part of an "ideal" solution?
@w-flo yeah, it's been 4 years and nobody's built it so the old pull request was probably better to merge than not. Do you want to rebase and reopen the last PR?
I've found this repo, which contains very great stuff, eg. gpx exporting with extensions in this file, perhaps even extension parsing.
also, uses this very crate (gpx
)
The GPX schema allows for some tags to include arbitrary XML data in the form of the
extensions
tag:Currently rust-gpx has no functionality that allows this data to be parsed or stored in the resulting
Gpx
instance. This issue is a tracking issue for this feature.