Aktuelle Nachrichten & Meldungen

Der Dotnet-Doktor: Auslesen und Sortieren von GPX-Dateien

Gepostet am Feb 1, 2016

Die Windows PowerShell biete eine schnelle Lösung für die Aufgabe, eine größere Menge von XML-Dateien zu sortieren.

Heute stellte sich mir die Aufgabe, eine größere Menge von Dateien im GPS Exchange Format (GPX) nach Jahren sortieren zu müssen. Es soll für jedes Jahr einen Ordner im Dateisystem geben, und alle GPX-Tracks, die in dem Jahr beginnen, sollen in den Ordner gelegt werden. Der Dateiname enthält keine Datumsinformationen.

GPX basiert auf XML, und die Datumsinformation sind dort im Tag <time> zu jedem Wegpunkt abgelegt. Ein Beispiel für einen Ausschnitt aus einer GPX-Datei:

 <?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.1"
creator="..."
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:topografix="http://www.topografix.com/GPX/Private/TopoGrafix/0/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.topografix.com/GPX/Private/TopoGrafix/0/1
http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd">
<metadata>
<name><![CDATA[...]]></name>
<desc><![CDATA[...]]></desc>
</metadata>
<trk>
<name><![CDATA...]]></name>
<desc><![CDATA[...]]></desc>
<type><![CDATA[...]]></type>
<trkseg>
<trkpt lat="51.356339" lon="6.946994">
<ele>195</ele>
<time>2015-05-02T12:31:01.950Z</time>
</trkpt>
<trkpt lat="51.356379" lon="6.946838">
<ele>172</ele>
<time>2015-05-02T12:31:12.785Z</time>
</trkpt>
...

Die Aufgabe konnte ich dank der guten XML-Unterstützung in der Windows PowerShell binnen 10 Minuten in der PowerShell-Skriptsprache lösen. Das nachstehende Listing zeigt das Ergebnis. Es wird in jeder GPX-Datei der erste Wegpunkt gesucht und dessen <time>-Tag ausgelesen.

Positiv erwähnen muss man, dass der PowerShell-Editor „ISE“ sogar Eingabeunterstützung für die XML-Elemente bietet (s. Abb.), d.h. anhand der tatsächlichen Struktur der Datei vorschlägt, was man nach $xml eingeben kann. Es stellt sich aber die Frage, woher der Editor die Struktur kennt, denn eine XML-Schemadatei wird ja nicht eingebunden. Der Trick ist, das Skript einmal bis zur Zeile [xml] $gpx = Get-Content $datei.FullName auszuführen und dann erst das Skript weiter zu erfassen. Dadurch ist die Variable $xml mit einem XmlDocument-Objekt befüllt, und der Editor kann Vorschläge machen.

XML-Intellisense in der ISE
XML-Eingabeunterstützung in der PowerShell ISE Vergrößern

 # Sortieren von GPX-Dateien nach Jahren
# (C) Dr. Holger Schwichtenberg 2016

$ErrorActionPreference = "stop"
$ordner = "t:\GPXDateien"
$dateien = dir $ordner -Filter *.gpx

# Schleife über alle Dateien
foreach($datei in $dateien)
{
$datei.Name
# Dateien laden und in XMLDocument umwandeln
[xml] $xml = Get-Content $datei.FullName
# Sonderfall prüfen: Ist die GPX-Datei leer?
if ($xml.gpx.trk.trkseg -eq $null)
{
$jahr = "leer"
}
else
{
# Datum extrahieren
[datetime] $dat = $xml.gpx.trk.trkseg.trkpt[0].time
$jahr = $dat.Year
}

# Jahresordner anlegen
$Jahresordner = $ordner + "\" + $jahr
if (-not (Test-Path $Jahresordner)) { md $Jahresordner }

# Datei in den Jahresordner verschieben
Move-Item $datei.FullName $Jahresordner
}

zusätzliche Lesung

passend zum Thema