tkrajina / gpxpy

gpx-py is a python GPX parser. GPX (GPS eXchange Format) is an XML based file format for GPS tracks.
Apache License 2.0
993 stars 223 forks source link

namespace information is saved incorrectly #184

Closed julie777 closed 4 years ago

julie777 commented 4 years ago

Garmin files have namespace information in the headers and use namespace references in the extensions field. When gpxpy opens a garmin file with extensions it works correctly, but when it saves that gpx file it incorrectly removes the namespace from the file header and expand the namespaces in all extension lines. The expansion is not quoted and contains '/' so it can not be parsed again later.

julie777 commented 4 years ago

garmin.gpx.txt bad.gpx.txt

tkrajina commented 4 years ago

I tried to reproduce this bug, but can't. Here's my test: https://github.com/tkrajina/gpxpy/commit/6c13f2df996533b56d22df4e888028b63a4b366c

Maybe it's related to a specific version of python and/or lxml? What version are you using? And, if it's python 2.* -- can you try with python 3.6+?

3add3287 commented 4 years ago

Are you creating new GPX files with gpxpy by opening an existing file, creating a new gpx object and then copying over some info? Asking b/c I had similar problems with invalid GPX files when doing this. When I copied the gpx object and serialized back to XML the syntax problem with GPX extensions disappeared. Unfortunately that triggers another problem and timezone offsets present in the time field gets lost as described in issues/190.

julie777 commented 4 years ago

Using the two files I uploaded, I load garmin.gpx and then save it as bad.gpx.

tkrajina commented 4 years ago

Here's what I tried:

import gpxpy

with open("garmin.gpx") as f:
    garmin_gpx = gpxpy.parse(f)

reparsed_gpx = gpxpy.parse(garmin_gpx.to_xml())
reparsed_gpx = gpxpy.parse(reparsed_gpx.to_xml())

print(reparsed_gpx.to_xml())

garmin.gpx is your garmin.gpx.txt

The first two lines of the result are:

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:adv="http://www.garmin.com/xmlschemas/AdventuresExtensions/v1" xmlns:ctx="http://www.garmin.com/xmlschemas/CreationTimeExtension/v1" xmlns:gpxacc="ht
tp://www.garmin.com/xmlschemas/AccelerationExtension/v1" xmlns:gpxpx="http://www.garmin.com/xmlschemas/PowerExtension/v1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:gpx
trx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:prs="http://www.garmin.com/xmlschemas/PressureExtension/v1" xmlns:tmd="http:/
/www.garmin.com/xmlschemas/TripMetaDataExtensions/v1" xmlns:trp="http://www.garmin.com/xmlschemas/TripExtensions/v1" xmlns:vidx1="http://www.garmin.com/xmlschemas/VideoExtension/v1" xmlns:vptm="http://w
ww.garmin.com/xmlschemas/ViaPointTransportationModeExtensions/v1" xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLoca
tion="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://w
ww.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensio
nsv3.xsd http://www.garmin.com/xmlschemas/ActivityExtension/v1 http://www8.garmin.com/xmlschemas/ActivityExtensionv1.xsd http://www.garmin.com/xmlschemas/AdventuresExtensions/v1 http://www8.garmin.com/x
mlschemas/AdventuresExtensionv1.xsd http://www.garmin.com/xmlschemas/PressureExtension/v1 http://www.garmin.com/xmlschemas/PressureExtensionv1.xsd http://www.garmin.com/xmlschemas/TripExtensions/v1 http://www.garmin.com/xmlschemas/TripExtensionsv1.xsd http://www.garmin.com/xmlschemas/TripMetaDataExtensions/v1 http://www.garmin.com/xmlschemas/TripMetaDataExtensionsv1.xsd http://www.garmin.com/xmlschemas/ViaPointTransportationModeExtensions/v1 http://www.garmin.com/xmlschemas/ViaPointTransportationModeExtensionsv1.xsd http://www.garmin.com/xmlschemas/CreationTimeExtension/v1 http://www.garmin.com/xmlschemas/CreationTimeExtensionsv1.xsd http://www.garmin.com/xmlschemas/AccelerationExtension/v1 http://www.garmin.com/xmlschemas/AccelerationExtensionv1.xsd http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd http://www.garmin.com/xmlschemas/VideoExtension/v1 http://www.garmin.com/xmlschemas/VideoExtensionv1.xsd" version="1.1" creator="Garmin Desktop App">

...but not...

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" 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" version="1.1" creator="gpx.py -- https://github.com/tkrajina/gpxpy">

...from your bad.gpx.

Anyway, I'll close this issue. I'll reopen it when/if I have a runnable example (possibly a test in test.py) to reproduce the bug.