Search code examples
xmlxsltgpx

XSL Stylesheet for gpx file


I have a gpx file that I made some edits to many of the "name" while it was in table format. Everything is ok except it moved the "name" entry after my "extensions" folder. It moved all the ones that I edited. I need them moved back to the correct location which is after "time". Some entries are "blank" which is ok. Here is a sample of the file I will just call MadeUp.gpx The 1st entry is correct but the 2nd one is in the wrong order. I just need everything sorted like the following MadeUp.gpx file. I have some software that will convert the file as long as the xsl template file is correct.

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:h="http://www.humminbird.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" creator="Humminbird PC 4.6.1 [Build20190411001]" version="1.1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
    <wpt lat="32.02994571203832" lon="-97.42508814212279">
        <ele />
        <time>2021-08-25T20:46:53Z</time>
        <name>Made Up</name>
        <desc />
        <sym>Fish</sym>
        <extensions>
            <h:uniqueid />
            <h:group>My Data</h:group>
            <h:edited />
            <h:visible>true</h:visible>
            <h:spotlock>false</h:spotlock>
            <h:creator />
            <h:viewas>IconOnly</h:viewas>
            <h:color>Magenta</h:color>
            <h:radiustoggle>false</h:radiustoggle>
            <h:radiussafety>false</h:radiussafety>
            <h:radius />
            <h:depth />
            <h:cursordepth />
            <h:temperature />
            <h:version>2</h:version>
        </extensions>
    </wpt>
    <wpt lat="32.03012171740864" lon="-97.42471086455052">
        <ele />
        <time>2021-08-25T20:46:53Z</time>
        <desc />
        <sym>Fish</sym>
        <extensions>
            <h:uniqueid />
            <h:group>My Data</h:group>
            <h:edited />
            <h:visible>true</h:visible>
            <h:spotlock>false</h:spotlock>
            <h:creator />
            <h:viewas>IconOnly</h:viewas>
            <h:color>Magenta</h:color>
            <h:radiustoggle>false</h:radiustoggle>
            <h:radiussafety>false</h:radiussafety>
            <h:radius />
            <h:depth />
            <h:cursordepth />
            <h:temperature />
            <h:version>2</h:version>
        </extensions>
        <name>Made Up</name>
    </wpt>
</gpx>

I have tried making an xsl template based on the correct format but when I convert the file, it gives me an error, "not a valid xml file. I have tried modifying some examples I have found online but none have worked correctly. I appreciate any help. Thanks for your time. Here is what I have for my xsl file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:h="www.humminbird.com" version="1.0">
    <xsl:output method="xml" encoding="utf-8" indent="no" />
    <xsl:template match="gpx">
        <xsl:text>;lat, lon,  Time, name, desc, sym, extensions, h:uniqueid, h:group, h:edited, h:visible, h:spotlock, h:creator, h:viewas, h:color, h:radiustoggle,h:radiussafety, h:radius, h:depth, h:cursordepth, h:temperature, h:version</xsl:text>
        <xsl:apply-templates select="wpt" />
    </xsl:template>
    <xsl:template match="wpt">
        <xsl:value-of select="@lat" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@lon" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="time" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="name" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="desc" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="sym" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="extensions" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:uniqueid" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:group" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:edited" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:visible" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:spotlock" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:creator" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:viewas" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:color" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:radiustoggle" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:radiussafety" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:radius" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:depth" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:cursordepth" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:temperature" />
        <xsl:text>,</xsl:text>
        <xsl:value-of select="h:version" />
        <xsl:text>,</xsl:text>
    </xsl:template>
</xsl:stylesheet>

Solution

  • Not sure what software you're using to do the transformation, so I'll assume you're restricted to XSLT 1.0.

    Here's how I would do it:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:gpx="http://www.topografix.com/GPX/1/1">
        <xsl:output indent="yes"/>
        <xsl:strip-space elements="*"/>
        
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="gpx:wpt">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()[not(self::gpx:name)]"/>
            </xsl:copy>
        </xsl:template>
        
        <xsl:template match="gpx:time">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
            <xsl:apply-templates select="../gpx:name"/>
        </xsl:template>
        
    </xsl:stylesheet>
    

    Working fiddle: http://xsltfiddle.liberty-development.net/gVAkJ4S