loc2gpx script

This perl script will convert a geocaching.com LOC file to a Garmin GPX file. Both files are XML, and writing this has renewed my hatred for XML as a bloated overcomplex format ill suited for 99% of the tasks put to it.

#!/usr/bin/perl

use strict;

use XML::Parser;
 
# initialize parser and read the file
my $parser = new XML::Parser( Style => 'Tree' );
my $tree = $parser->parsefile( shift @ARGV );

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime();
my $timeString = sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",$year+1900,$mon+1,$mday,$hour,$min,$sec);

print <<EOL;
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gpx xmlns="http://www.topografix.com/GPX/1/1"
xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"
creator="D???????????????" version="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 http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd">


<metadata>
	<link href="http://dsss.be/">
		<text>Tyler's loc2gpx</text>
	</link>
	<time>$timeString</time>
</metadata>

EOL




# god damn I hate XML
for (my $i=0; $i<@{$tree->[1]}; $i++) {
	my $waypoint;
	if ($tree->[1][$i] eq 'waypoint') {
		$i++;
		$waypoint = $tree->[1][$i];
	} else {
		next;
	}
	my $id = $waypoint->[4][0]{'id'};
	my $name = $waypoint->[4][2];
	my $lat = $waypoint->[8][0]{'lat'};
	my $lon = $waypoint->[8][0]{'lon'};
	my $link = $waypoint->[16][2];
	print <<EOL;
		<wpt lat="$lat" lon="$lon">
			<name>($id) $name</name>
			<sym>Geocache</sym>
		</wpt>
		
EOL
}


print "</gpx>\n";