aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2011-09-19 16:57:53 +0200
committerBananeweizen <bananeweizen@gmx.de>2011-09-19 16:57:53 +0200
commit035e145e4cfea3434481d9182843efec6ce258d5 (patch)
tree355386e4ecb57b93cc6c9f7d7b778533954660bb
parent418a3902ef9c3b6a51a78fe9c024d4ad2ab07f4f (diff)
downloadcgeo-035e145e4cfea3434481d9182843efec6ce258d5.zip
cgeo-035e145e4cfea3434481d9182843efec6ce258d5.tar.gz
cgeo-035e145e4cfea3434481d9182843efec6ce258d5.tar.bz2
* have static dictionaries in cgBase initialized in static section
(necessary for some unit tests) * have singleton of application instance, allows removing all the "app" fields everywhere afterwards * refactor GPX parser to be independent of c:geo application classes, so it can be tested much easier * new unit tests for different GPX versions and sources * new unit tests for LOC file parsing
-rw-r--r--main/src/cgeo/geocaching/cgBase.java11
-rw-r--r--main/src/cgeo/geocaching/cgeoapplication.java6
-rw-r--r--main/src/cgeo/geocaching/cgeogpxes.java14
-rw-r--r--main/src/cgeo/geocaching/files/FileParser.java9
-rw-r--r--main/src/cgeo/geocaching/files/GPX10Parser.java8
-rw-r--r--main/src/cgeo/geocaching/files/GPX11Parser.java8
-rw-r--r--main/src/cgeo/geocaching/files/GPXParser.java118
-rw-r--r--main/src/cgeo/geocaching/files/LocParser.java16
-rw-r--r--tests/res/raw/gc1bkp3_gpx100.gpx209
-rw-r--r--tests/res/raw/gc1bkp3_gpx101.gpx221
-rw-r--r--tests/res/raw/gc1bkp3_loc.loc12
-rw-r--r--tests/res/raw/oc5952_gpx.gpx80
-rw-r--r--tests/res/raw/oc5952_loc.loc9
-rw-r--r--tests/src/cgeo/geocaching/test/GPXParserTest.java89
-rw-r--r--tests/src/cgeo/geocaching/test/LocParserTest.java64
15 files changed, 791 insertions, 83 deletions
diff --git a/main/src/cgeo/geocaching/cgBase.java b/main/src/cgeo/geocaching/cgBase.java
index 3e132f8..2ee29c7 100644
--- a/main/src/cgeo/geocaching/cgBase.java
+++ b/main/src/cgeo/geocaching/cgBase.java
@@ -1,6 +1,7 @@
package cgeo.geocaching;
import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.connector.opencaching.OkapiClient;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.WaypointType;
@@ -129,8 +130,14 @@ public class cgBase {
private final static Pattern PATTERN_TRACKABLE_Log = Pattern.compile("<tr class=\"Data.+?src=\"/images/icons/([^.]+)\\.gif[^>]+>&nbsp;([^<]+)</td>.+?guid.+?>([^<]+)</a>.+?(?:guid=([^\"]+)\">([^<]+)</a>.+?)?<td colspan=\"4\">(.+?)(?:<ul.+?ul>)?\\s*</td>\\s*</tr>", Pattern.CASE_INSENSITIVE);
public final static Map<String, String> cacheTypes = new HashMap<String, String>();
- public final static Map<String, String> cacheTypesInv = new HashMap<String, String>();
public final static Map<String, String> cacheIDs = new HashMap<String, String>();
+ static {
+ for (CacheType ct : CacheType.values()) {
+ cacheTypes.put(ct.pattern, ct.id);
+ cacheIDs.put(ct.id, ct.guid);
+ }
+ }
+ public final static Map<String, String> cacheTypesInv = new HashMap<String, String>();
public final static Map<String, String> cacheIDsChoices = new HashMap<String, String>();
public final static Map<CacheSize, String> cacheSizesInv = new HashMap<CacheSize, String>();
public final static Map<String, String> waypointTypes = new HashMap<String, String>();
@@ -223,9 +230,7 @@ public class cgBase {
for (CacheType ct : CacheType.values()) {
String l10n = res.getString(ct.stringId);
- cacheTypes.put(ct.pattern, ct.id);
cacheTypesInv.put(ct.id, l10n);
- cacheIDs.put(ct.id, ct.guid);
cacheIDsChoices.put(l10n, ct.guid);
}
diff --git a/main/src/cgeo/geocaching/cgeoapplication.java b/main/src/cgeo/geocaching/cgeoapplication.java
index d7571b2..2b9f919 100644
--- a/main/src/cgeo/geocaching/cgeoapplication.java
+++ b/main/src/cgeo/geocaching/cgeoapplication.java
@@ -31,13 +31,19 @@ public class cgeoapplication extends Application {
public boolean showLoginToast = true; //login toast shown just once.
public boolean warnedLanguage = false; // user was warned about different language settings on geocaching.com
private boolean databaseCleaned = false; // database was cleaned
+ private static cgeoapplication instance;
public cgeoapplication() {
+ instance = this;
if (storage == null) {
storage = new cgData(this);
}
}
+ public static cgeoapplication getInstance() {
+ return instance;
+ }
+
@Override
public void onLowMemory() {
Log.i(cgSettings.tag, "Cleaning applications cache.");
diff --git a/main/src/cgeo/geocaching/cgeogpxes.java b/main/src/cgeo/geocaching/cgeogpxes.java
index e3e9ba6..4f32676 100644
--- a/main/src/cgeo/geocaching/cgeogpxes.java
+++ b/main/src/cgeo/geocaching/cgeogpxes.java
@@ -21,9 +21,7 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
private static final String EXTRAS_LIST_ID = "list";
public cgeogpxes() {
- super(new String[] { "gpx"
- // TODO , "loc"
- });
+ super(new String[] { "gpx", "loc" });
}
private ProgressDialog parseDialog = null;
@@ -65,7 +63,7 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
@Override
protected String[] getBaseFolders() {
- String base = Environment.getExternalStorageDirectory().toString();
+ final String base = Environment.getExternalStorageDirectory().toString();
return new String[] { base + "/gpx" };
}
@@ -73,7 +71,7 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Bundle extras = getIntent().getExtras();
+ final Bundle extras = getIntent().getExtras();
if (extras != null) {
listId = extras.getInt(EXTRAS_LIST_ID);
}
@@ -111,12 +109,12 @@ public class cgeogpxes extends FileList<cgGPXListAdapter> {
@Override
public void run() {
final UUID searchId;
- String name = file.getName().toLowerCase();
+ final String name = file.getName().toLowerCase();
if (name.endsWith("gpx")) {
- searchId = GPXParser.parseGPX(app, file, listId, changeParseDialogHandler);
+ searchId = GPXParser.parseGPX(file, listId, changeParseDialogHandler);
}
else {
- searchId = LocParser.parseLoc(app, file, listId, changeParseDialogHandler);
+ searchId = LocParser.parseLoc(file, listId, changeParseDialogHandler);
}
imported = app.getCount(searchId);
diff --git a/main/src/cgeo/geocaching/files/FileParser.java b/main/src/cgeo/geocaching/files/FileParser.java
index 158d390..c92b6d2 100644
--- a/main/src/cgeo/geocaching/files/FileParser.java
+++ b/main/src/cgeo/geocaching/files/FileParser.java
@@ -2,7 +2,6 @@ package cgeo.geocaching.files;
import cgeo.geocaching.cgBase;
import cgeo.geocaching.cgCache;
-import cgeo.geocaching.cgSearch;
import android.os.Handler;
import android.os.Message;
@@ -17,8 +16,8 @@ import java.util.Date;
public abstract class FileParser {
protected static StringBuilder readFile(File file)
throws FileNotFoundException, IOException {
- StringBuilder buffer = new StringBuilder();
- BufferedReader input = new BufferedReader(new FileReader(file));
+ final StringBuilder buffer = new StringBuilder();
+ final BufferedReader input = new BufferedReader(new FileReader(file));
try {
String line = null;
while ((line = input.readLine()) != null) {
@@ -30,10 +29,10 @@ public abstract class FileParser {
return buffer;
}
- static void showFinishedMessage(Handler handler, cgSearch search) {
+ protected static void showCountMessage(final Handler handler, final int count) {
if (handler != null) {
final Message msg = new Message();
- msg.obj = search.getCount();
+ msg.obj = count;
handler.sendMessage(msg);
}
}
diff --git a/main/src/cgeo/geocaching/files/GPX10Parser.java b/main/src/cgeo/geocaching/files/GPX10Parser.java
index c3b95b2..85884de 100644
--- a/main/src/cgeo/geocaching/files/GPX10Parser.java
+++ b/main/src/cgeo/geocaching/files/GPX10Parser.java
@@ -1,15 +1,11 @@
package cgeo.geocaching.files;
-import cgeo.geocaching.cgSearch;
-import cgeo.geocaching.cgeoapplication;
-
import android.sax.Element;
public final class GPX10Parser extends GPXParser {
- public GPX10Parser(cgeoapplication appIn, int listIdIn,
- cgSearch searchIn) {
- super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/0", "1.0");
+ public GPX10Parser(int listIdIn) {
+ super(listIdIn, "http://www.topografix.com/GPX/1/0", "1.0");
}
@Override
diff --git a/main/src/cgeo/geocaching/files/GPX11Parser.java b/main/src/cgeo/geocaching/files/GPX11Parser.java
index 4c8960b..52a6ae3 100644
--- a/main/src/cgeo/geocaching/files/GPX11Parser.java
+++ b/main/src/cgeo/geocaching/files/GPX11Parser.java
@@ -1,15 +1,11 @@
package cgeo.geocaching.files;
-import cgeo.geocaching.cgSearch;
-import cgeo.geocaching.cgeoapplication;
-
import android.sax.Element;
public final class GPX11Parser extends GPXParser {
- public GPX11Parser(cgeoapplication appIn, int listIdIn,
- cgSearch searchIn) {
- super(appIn, listIdIn, searchIn, "http://www.topografix.com/GPX/1/1", "1.1");
+ public GPX11Parser(int listIdIn) {
+ super(listIdIn, "http://www.topografix.com/GPX/1/1", "1.1");
}
@Override
diff --git a/main/src/cgeo/geocaching/files/GPXParser.java b/main/src/cgeo/geocaching/files/GPXParser.java
index 6412564..a424532 100644
--- a/main/src/cgeo/geocaching/files/GPXParser.java
+++ b/main/src/cgeo/geocaching/files/GPXParser.java
@@ -34,6 +34,7 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -45,17 +46,21 @@ public abstract class GPXParser extends FileParser {
private static final Pattern patternGeocode = Pattern.compile("([A-Z]{2}[0-9A-Z]+)", Pattern.CASE_INSENSITIVE);
private static final Pattern patternGuid = Pattern.compile(".*" + Pattern.quote("guid=") + "([0-9a-z\\-]+)", Pattern.CASE_INSENSITIVE);
+ /**
+ * supported groundspeak extensions of the GPX format
+ */
private static final String[] nsGCList = new String[] {
"http://www.groundspeak.com/cache/1/1", // PQ 1.1
"http://www.groundspeak.com/cache/1/0/1", // PQ 1.0.1
"http://www.groundspeak.com/cache/1/0", // PQ 1.0
};
+ /**
+ * supported GSAK extension of the GPX format
+ */
private static final String GSAK_NS = "http://www.gsak.net/xmlv1/5";
- private static cgeoapplication app = null;
private int listId = 1;
- private cgSearch search = null;
final protected String namespace;
final private String version;
private Handler handler = null;
@@ -69,10 +74,10 @@ public abstract class GPXParser extends FileParser {
private String name = null;
private String cmt = null;
private String desc = null;
- protected String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier
+ protected final String[] userData = new String[5]; // take 5 cells, that makes indexing 1..4 easier
private final class UserDataListener implements EndTextElementListener {
- private int index;
+ private final int index;
public UserDataListener(int index) {
this.index = index;
@@ -175,7 +180,7 @@ public abstract class GPXParser extends FileParser {
// get text for string
String stringName = null;
try {
- stringName = app.getResources().getResourceName(stringId);
+ stringName = cgeoapplication.getInstance().getResources().getResourceName(stringId);
} catch (NullPointerException e) {
return null;
}
@@ -200,10 +205,8 @@ public abstract class GPXParser extends FileParser {
}
}
- protected GPXParser(cgeoapplication appIn, int listIdIn, cgSearch searchIn, String namespaceIn, String versionIn) {
- app = appIn;
+ protected GPXParser(int listIdIn, String namespaceIn, String versionIn) {
listId = listIdIn;
- search = searchIn;
namespace = namespaceIn;
version = versionIn;
}
@@ -217,8 +220,9 @@ public abstract class GPXParser extends FileParser {
return formatSimple.parse(input);
}
- public UUID parse(final InputStream stream, Handler handlerIn) {
+ public List<cgCache> parse(final InputStream stream, Handler handlerIn) {
handler = handlerIn;
+ final List<cgCache> result = new ArrayList<cgCache>();
final RootElement root = new RootElement(namespace, "gpx");
final Element waypoint = root.getChild(namespace, "wpt");
@@ -260,24 +264,12 @@ public abstract class GPXParser extends FileParser {
cache.reason = listId;
cache.detailed = true;
- if (StringUtils.isBlank(cache.personalNote)) {
- StringBuilder buffer = new StringBuilder();
- for (int i = 0; i < userData.length; i++) {
- if (StringUtils.isNotBlank(userData[i])) {
- buffer.append(' ').append(userData[i]);
- }
- }
- String note = buffer.toString().trim();
- if (StringUtils.isNotBlank(note)) {
- cache.personalNote = note;
- }
- }
+ createNoteFromGSAKUserdata();
- app.addCacheToSearch(search, cache);
+ result.add(cache);
+ showCountMessage(handler, result.size());
}
- showFinishedMessage(handler, search);
-
resetCache();
}
});
@@ -364,7 +356,7 @@ public abstract class GPXParser extends FileParser {
public void end(String url) {
final Matcher matcher = patternGuid.matcher(url);
if (matcher.matches()) {
- String guid = matcher.group(1);
+ final String guid = matcher.group(1);
if (StringUtils.isNotBlank(guid)) {
cache.guid = guid;
}
@@ -698,16 +690,17 @@ public abstract class GPXParser extends FileParser {
} catch (SAXException e) {
Log.e(cgSettings.tag, "Cannot parse .gpx file as GPX " + version + ": could not parse XML - " + e.toString());
}
- return parsed ? search.getCurrentId() : null;
+
+ return parsed ? result : null;
}
- private UUID parse(final File file, final Handler handlerIn) {
+ private List<cgCache> parse(final File file, final Handler handlerIn) {
if (file == null) {
return null;
}
FileInputStream fis = null;
- UUID result = null;
+ List<cgCache> result = null;
try {
fis = new FileInputStream(file);
result = parse(fis, handlerIn);
@@ -724,6 +717,13 @@ public abstract class GPXParser extends FileParser {
return result;
}
+ /**
+ * GPX 1.0 and 1.1 use different XML elements to put the cache into, therefore needs to be overwritten in the
+ * version specific subclasses
+ *
+ * @param waypoint
+ * @return
+ */
protected abstract Element getCacheParent(Element waypoint);
protected static String validate(String input) {
@@ -733,8 +733,9 @@ public abstract class GPXParser extends FileParser {
return input.trim();
}
- private void setType(String parsedString) {
- final String knownType = cgBase.cacheTypes.get(parsedString);
+ private void setType(final String parsedString) {
+ String lowercase = parsedString.toLowerCase().trim();
+ final String knownType = cgBase.cacheTypes.get(lowercase);
if (knownType != null) {
cache.type = knownType;
}
@@ -751,15 +752,16 @@ public abstract class GPXParser extends FileParser {
}
final Matcher matcherGeocode = patternGeocode.matcher(input);
if (matcherGeocode.find()) {
- if (matcherGeocode.groupCount() > 0) {
- final String geocode = matcherGeocode.group(1);
- if (ConnectorFactory.canHandle(geocode)) {
- cache.geocode = geocode;
- }
+ final String geocode = matcherGeocode.group(1);
+ if (ConnectorFactory.canHandle(geocode)) {
+ cache.geocode = geocode;
}
}
}
+ /**
+ * reset all fields that are used to store cache fields over the duration of parsing a single cache
+ */
private void resetCache() {
type = null;
sym = null;
@@ -773,23 +775,47 @@ public abstract class GPXParser extends FileParser {
}
}
- public static UUID parseGPX(cgeoapplication app, File file, int listId, Handler handler) {
- final cgSearch search = new cgSearch();
- UUID searchId = null;
+ /**
+ * create a cache note from the UserData1 to UserData4 fields supported by GSAK
+ */
+ private void createNoteFromGSAKUserdata() {
+ if (StringUtils.isBlank(cache.personalNote)) {
+ final StringBuilder buffer = new StringBuilder();
+ for (int i = 0; i < userData.length; i++) {
+ if (StringUtils.isNotBlank(userData[i])) {
+ buffer.append(' ').append(userData[i]);
+ }
+ }
+ final String note = buffer.toString().trim();
+ if (StringUtils.isNotBlank(note)) {
+ cache.personalNote = note;
+ }
+ }
+ }
+ public static UUID parseGPX(File file, int listId, Handler handler) {
try {
- GPXParser parser = new GPX10Parser(app, listId, search);
- searchId = parser.parse(file, handler);
- if (searchId == null) {
- parser = new GPX11Parser(app, listId, search);
- searchId = parser.parse(file, handler);
+ GPXParser parser = new GPX10Parser(listId);
+ List<cgCache> caches = parser.parse(file, handler);
+ if (caches == null) {
+ parser = new GPX11Parser(listId);
+ caches = parser.parse(file, handler);
}
+
+ if (caches != null) {
+ final cgSearch search = new cgSearch();
+ final cgeoapplication app = cgeoapplication.getInstance();
+ for (cgCache cache : caches) {
+ app.addCacheToSearch(search, cache);
+ }
+ Log.i(cgSettings.tag, "Caches found in .gpx file: " + caches.size());
+ return search.getCurrentId();
+ }
+
} catch (Exception e) {
Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString());
}
- Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId));
-
- return search.getCurrentId();
+ return null;
}
}
diff --git a/main/src/cgeo/geocaching/files/LocParser.java b/main/src/cgeo/geocaching/files/LocParser.java
index 240d61d..3bb69cd 100644
--- a/main/src/cgeo/geocaching/files/LocParser.java
+++ b/main/src/cgeo/geocaching/files/LocParser.java
@@ -63,7 +63,7 @@ public final class LocParser extends FileParser {
}
}
- private static Map<String, cgCoord> parseCoordinates(
+ public static Map<String, cgCoord> parseCoordinates(
final String fileContent) {
final Map<String, cgCoord> coords = new HashMap<String, cgCoord>();
if (StringUtils.isBlank(fileContent)) {
@@ -141,13 +141,12 @@ public final class LocParser extends FileParser {
return coords;
}
- public static UUID parseLoc(cgeoapplication app, File file, int listId,
+ public static UUID parseLoc(File file, int listId,
Handler handler) {
- cgSearch search = new cgSearch();
- UUID searchId = null;
+ final cgSearch search = new cgSearch();
try {
- Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
+ final Map<String, cgCoord> coords = parseCoordinates(readFile(file).toString());
final cgCacheWrap caches = new cgCacheWrap();
for (Entry<String, cgCoord> entry : coords.entrySet()) {
cgCoord coord = entry.getValue();
@@ -162,16 +161,15 @@ public final class LocParser extends FileParser {
cache.reason = listId;
cache.detailed = false;
- app.addCacheToSearch(search, cache);
+ cgeoapplication.getInstance().addCacheToSearch(search, cache);
}
caches.totalCnt = caches.cacheList.size();
- showFinishedMessage(handler, search);
+ showCountMessage(handler, search.getCount());
+ Log.i(cgSettings.tag, "Caches found in .gpx file: " + caches.totalCnt);
} catch (Exception e) {
Log.e(cgSettings.tag, "cgBase.parseGPX: " + e.toString());
}
- Log.i(cgSettings.tag, "Caches found in .gpx file: " + app.getCount(searchId));
-
return search.getCurrentId();
}
}
diff --git a/tests/res/raw/gc1bkp3_gpx100.gpx b/tests/res/raw/gc1bkp3_gpx100.gpx
new file mode 100644
index 0000000..5cd8d04
--- /dev/null
+++ b/tests/res/raw/gc1bkp3_gpx100.gpx
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8"?>
+<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0" creator="Groundspeak, Inc. All Rights Reserved. http://www.groundspeak.com" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0 http://www.groundspeak.com/cache/1/0/cache.xsd" xmlns="http://www.topografix.com/GPX/1/0">
+ <name>Cache Listing Generated from Geocaching.com</name>
+ <desc>This is an individual cache generated from Geocaching.com</desc>
+ <author>Account "Die unbesiegbaren Geo - Geparden" From Geocaching.com</author>
+ <email>contact@geocaching.com</email>
+ <url>http://www.geocaching.com</url>
+ <urlname>Geocaching - High Tech Treasure Hunting</urlname>
+ <time>2011-09-18T07:28:20.2343179Z</time>
+ <keywords>cache, geocache</keywords>
+ <bounds minlat="48.859683" minlon="9.1874" maxlat="48.859683" maxlon="9.1874" />
+ <wpt lat="48.859683" lon="9.1874">
+ <time>2008-01-09T08:00:00Z</time>
+ <name>GC1BKP3</name>
+ <desc>Die Schatzinsel / treasure island by Die unbesiegbaren Geo - Geparden, Traditional Cache (1/5)</desc>
+ <url>http://www.geocaching.com/seek/cache_details.aspx?guid=9946f030-a514-46d8-a050-a60e92fd2e1a</url>
+ <urlname>Die Schatzinsel / treasure island</urlname>
+ <sym>Geocache</sym>
+ <type>Geocache|Traditional Cache</type>
+ <groundspeak:cache id="859046" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0">
+ <groundspeak:name>Die Schatzinsel / treasure island</groundspeak:name>
+ <groundspeak:placed_by>Die unbesiegbaren Geo - Geparden</groundspeak:placed_by>
+ <groundspeak:owner id="1003143">Die unbesiegbaren Geo - Geparden</groundspeak:owner>
+ <groundspeak:type>Traditional Cache</groundspeak:type>
+ <groundspeak:container>Micro</groundspeak:container>
+ <groundspeak:difficulty>1</groundspeak:difficulty>
+ <groundspeak:terrain>5</groundspeak:terrain>
+ <groundspeak:country>Germany</groundspeak:country>
+ <groundspeak:state>Baden-Württemberg</groundspeak:state>
+ <groundspeak:short_description html="False">Ein alter Kindheitstraum, ein Schatz auf einer unbewohnten Insel.
+A old dream of my childhood, a treasure on a lonely island.</groundspeak:short_description>
+ <groundspeak:long_description html="False">Startinhalt:
+Logbuch
+Taschenmesser
+Feuerzeug
+Ziege
+Walross
+Löwe
+
+Bitte achtet am Uferbereich auf brütende Vögel, passt auch auf eure Kinder auf.
+Betreten des Eises auf eigene Gefahr, auch hier gilt die Aufmerksamkeit den Kindern.</groundspeak:long_description>
+ <groundspeak:encoded_hints>Der Klassiker schlechthin, ein Micro im Baumstumpf, nicht originell, dafür evtl. muggelsicherer</groundspeak:encoded_hints>
+ <groundspeak:logs>
+ <groundspeak:log id="186034406">
+ <groundspeak:date>2011-09-09T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="279140">Sprenzl</groundspeak:finder>
+ <groundspeak:text encoded="False">... noch am Vorabend unserer Reise zur "10-Icons-Dy-Tour" ein paar Caches in Stuttgart gemacht und dabei sind wir auch an dieser Dose vorbeigekommen [:D] !! Vielen Dank an alle owner für die teils pfiffig gemachten Dosen !!
+
+Zum Glück hatten wir die richtige Ausrüstung im Cachemobil !!
+
+TFTC !!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="177991444">
+ <groundspeak:date>2011-08-07T07:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="742581">tmueller78</groundspeak:finder>
+ <groundspeak:text encoded="False">Mal was ganz anderes!
+Das Logbuch ist allerdings auch recht feucht, wenn auch nicht ganz so sehr wie der Weg...
+Vielen dank!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175939075">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="90014">Landmaus</groundspeak:finder>
+ <groundspeak:text encoded="False">Auf großer LB-Asperg Runde gefunden. Vor langem schon mal im Winter ohne Equipment probiert, heute hats gepasst.
+Hat Spaß gemacht in bekannter Gegend mal nach einem Jahr wieder rumzuziehen.
+Danke und bis bald im Wald
+Landmaus</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175039530">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1270295">bcas008</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute beim Dosenfischen auch hier vorbeigekommen und das Döslein auch fix bewaffnet mit Watthose gefunden. Somit stand dem Logbucheintrag nichts mehr im Weg.
+
+T4TC und fürs zeigen
+grüssle BCAS008</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175016395">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1297335">caperdonich</groundspeak:finder>
+ <groundspeak:text encoded="False">Im Team hier vorbeigekommen und nach kurzer Suche (und mit der Wathose bekleidet) konnten wir uns im Logbuch verewigen.
+TFTC und fürs Herlocken.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175011227">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2529739">Lemmer</groundspeak:finder>
+ <groundspeak:text encoded="False">Auf großer Tour heute war für alle was dabei raufklettern, reinkrabbeln, ausrätseln und natürlich viel rumsuchen und laufen laufen laufen. Sehr witzig Gummihose sei Dank, hat uns gut gefallen im Wasser zu planschen. Vielen Dank fürs erfinden und verstecken. Lemmer</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="171966035">
+ <groundspeak:date>2011-07-08T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2519606">Luftretter</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute im Team mit Kati100 hier vorbeigeschaut, kurz die Lage erkundet, beschlossen dass Boot a) zu arg auffällt und b) ohne Luftpumpe [:I] eh doof ist und dann mittels Plan B [;)] zugeschlagen. [:P]
+
+DFDC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="168208824">
+ <groundspeak:date>2011-06-20T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1117070">Detection</groundspeak:finder>
+ <groundspeak:text encoded="False">Da SkyTrain und ich noch ein wenig Urlaub hatten, sind wir in der Gegend von Kletterdose zu Kletterdose geschlendert.
+hier war plantschen angesagt und so gesellten wir uns zu den Enten. Wegen der Küken mussten wir aufpassen nicht von den Eltern angegriffen zu werden. Ein kleiner Badespaß am frühen Morgen ohne Muggel.
+
+TFTC, Detection</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="168204217">
+ <groundspeak:date>2011-06-20T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2044578">SkyTrain</groundspeak:finder>
+ <groundspeak:text encoded="False">Zusammen mit Detection ging es durchs Stuttgarter Umlang um ein paar Sterne zu fangen.
+
+Vor einem Jahr stand ich schon mal an diesem Teich. Damals war gerade Pause und dutzende von Schulkindern tummelten sich rund um den „See“. Da wollten wir uns nicht zum Affen machen. Heute, bei leichtem Regen, war der Platz leer und der Suche nach dem Schatz stand nichts im Wege. Hat Spaß gemacht mal wieder die Gummihose durchzuspülen.
+
+Danke für den Cache
+Viele Grüße
+SkyTrain</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="162038232">
+ <groundspeak:date>2011-05-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="849709">asti_2000</groundspeak:finder>
+ <groundspeak:text encoded="False">Obwohl gegenüber gerade ein Feschtle aufgbaut wurde relativ entspannt rübergewatschelt. Erstaunlich eben und aufgeräumt der Boden. Die Enten hat's gefreut! Endlich wurde mal neue Nahrung aufgewirbelt.
+also aktiver Naturschutz!!!
+TFTC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="161952671">
+ <groundspeak:date>2011-05-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3006671">Zanderhenry</groundspeak:finder>
+ <groundspeak:text encoded="False">Mit Wathose trockenen Fußes das das Dösle erreicht.Danke für den Cache.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="159587854">
+ <groundspeak:date>2011-05-07T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="3946618">Affenpingu</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute begann unsere Cachingrunde nicht gut, es gab gleich mehrer Cache's unter anderem auch dieser, welche wir mal wieder wegen der Dorfjugend abbrechen mussten.
+
+Affenpingu</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="156042992">
+ <groundspeak:date>2011-04-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3353624">Benja.</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute waren wir mit zwei Gastcachern unterwegs. Da zu dieser Zeit der See nicht zugefroren war, musste die Wathose herhalten. Damit gings auch fix auf die Schatzinsel. Jedoch wollte sich die Dose nicht so schnell zeigen. Unsere weibliche Gastcacherin wurde schließlich fündig.
+Vielen Dank für den tollen Cache, wir hatten wirklich Spaß [:D].
+
+Benja
+
+This entry was edited by Benja. on Monday, 25 April 2011 at 09:23:58 UTC.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143643778">
+ <groundspeak:date>2011-02-04T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="2981424">BlackHawk112</groundspeak:finder>
+ <groundspeak:text encoded="False">knack, knack, knack, ach verdammt, 2 meter vor der insel musste ich schnellstmöglich und gaaaaaaaaaanz vorsichtig umdrehen.
+das eis ist bei 4,5 C° PLUS wohl doch nicht mehr so stabil und bei meinen 85 kilo hing das eis doch schon etwas durch =(
+mhmm und es war auch kein kind in der nähe das man sich kurz borgen konnte =)
+kann mir den einer sein kind kurz leihen ;-) nein scherz, dann muss ich wann anders wieder kommen</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143570318">
+ <groundspeak:date>2011-02-03T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="4034367">slowjoe66</groundspeak:finder>
+ <groundspeak:text encoded="False">Oh man das Eis hat gekracht wie die sau, aber zum Glück noch trokenen Fußes rüber gekommen.
+dfdc ist ne klasse Idee, slowjoe66</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143573844">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2983866">Julia77</groundspeak:finder>
+ <groundspeak:text encoded="False">Hält es? Hält es? Hält es? Ja, es hält!!! Und auf dem Rückweg??? - Zwar war der T5-er bei Eis nicht die große technische Herausforderung, aber der Adrenalinpegel war wegen des Knackens im Eis trotzdem hoch genug... ;-) Danke für den Cache!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143540120">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3949535">Alcinoo</groundspeak:finder>
+ <groundspeak:text encoded="False">Eis hat noch gut gehalten. So wars wirklich nicht zu schwer. Danke.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143538986">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2007162">Zoidberg2678</groundspeak:finder>
+ <groundspeak:text encoded="False">Knack, kanck. Aber es hat gehalten. Wir sind zu Dritt wohlbehalten rüber gekommen und genauso zurück. TFTC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143511134">
+ <groundspeak:date>2011-02-02T08:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2385317">Titschi</groundspeak:finder>
+ <groundspeak:text encoded="False">Huuu, Eis hielt noch :)
+
+Tftc, Titschi</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="140433464">
+ <groundspeak:date>2011-01-05T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2024532">cjotle</groundspeak:finder>
+ <groundspeak:text encoded="False">Da die Kinder vom Schlitten fahren genug haben, heute mal wieder einen Cache als Frischluftprogramm angegriffen. Hier wollten wir schon mal vor 2 Jahren im Winter zuschlagen, aber da waren die Kinder noch jünger und konnten sich nicht "unauffällig" verhalten. Heute quasi zeitgleich mit Doc Brown an der Insel angekommen und gemeinsam schnell gefunden.
+Danke für den heute trockenen Fußes erreichbaren Cache.
+jotl von der cjolte-Familie</groundspeak:text>
+ </groundspeak:log>
+ </groundspeak:logs>
+ <groundspeak:travelbugs />
+ </groundspeak:cache>
+ </wpt>
+</gpx> \ No newline at end of file
diff --git a/tests/res/raw/gc1bkp3_gpx101.gpx b/tests/res/raw/gc1bkp3_gpx101.gpx
new file mode 100644
index 0000000..be9eeb3
--- /dev/null
+++ b/tests/res/raw/gc1bkp3_gpx101.gpx
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="utf-8"?>
+<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0" creator="Groundspeak, Inc. All Rights Reserved. http://www.groundspeak.com" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd" xmlns="http://www.topografix.com/GPX/1/0">
+ <name>Cache Listing Generated from Geocaching.com</name>
+ <desc>This is an individual cache generated from Geocaching.com</desc>
+ <author>Account "Die unbesiegbaren Geo - Geparden" From Geocaching.com</author>
+ <email>contact@geocaching.com</email>
+ <url>http://www.geocaching.com</url>
+ <urlname>Geocaching - High Tech Treasure Hunting</urlname>
+ <time>2011-09-18T07:25:47.5256496Z</time>
+ <keywords>cache, geocache</keywords>
+ <bounds minlat="48.859683" minlon="9.1874" maxlat="48.859683" maxlon="9.1874" />
+ <wpt lat="48.859683" lon="9.1874">
+ <time>2008-01-09T08:00:00Z</time>
+ <name>GC1BKP3</name>
+ <desc>Die Schatzinsel / treasure island by Die unbesiegbaren Geo - Geparden, Traditional Cache (1/5)</desc>
+ <url>http://www.geocaching.com/seek/cache_details.aspx?guid=9946f030-a514-46d8-a050-a60e92fd2e1a</url>
+ <urlname>Die Schatzinsel / treasure island</urlname>
+ <sym>Geocache</sym>
+ <type>Geocache|Traditional Cache</type>
+ <groundspeak:cache id="859046" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0/1">
+ <groundspeak:name>Die Schatzinsel / treasure island</groundspeak:name>
+ <groundspeak:placed_by>Die unbesiegbaren Geo - Geparden</groundspeak:placed_by>
+ <groundspeak:owner id="1003143">Die unbesiegbaren Geo - Geparden</groundspeak:owner>
+ <groundspeak:type>Traditional Cache</groundspeak:type>
+ <groundspeak:container>Micro</groundspeak:container>
+ <groundspeak:attributes>
+ <groundspeak:attribute id="41" inc="0">Stroller accessible</groundspeak:attribute>
+ <groundspeak:attribute id="24" inc="0">Wheelchair accessible</groundspeak:attribute>
+ <groundspeak:attribute id="19" inc="1">Ticks</groundspeak:attribute>
+ <groundspeak:attribute id="15" inc="1">Available during winter</groundspeak:attribute>
+ <groundspeak:attribute id="13" inc="1">Available at all times</groundspeak:attribute>
+ <groundspeak:attribute id="12" inc="1">May require swimming</groundspeak:attribute>
+ <groundspeak:attribute id="11" inc="1">May require wading</groundspeak:attribute>
+ <groundspeak:attribute id="30" inc="1">Picnic tables nearby</groundspeak:attribute>
+ <groundspeak:attribute id="7" inc="1">Takes less than an hour</groundspeak:attribute>
+ <groundspeak:attribute id="29" inc="1">Telephone nearby</groundspeak:attribute>
+ </groundspeak:attributes>
+ <groundspeak:difficulty>1</groundspeak:difficulty>
+ <groundspeak:terrain>5</groundspeak:terrain>
+ <groundspeak:country>Germany</groundspeak:country>
+ <groundspeak:state>Baden-Württemberg</groundspeak:state>
+ <groundspeak:short_description html="False">Ein alter Kindheitstraum, ein Schatz auf einer unbewohnten Insel.
+A old dream of my childhood, a treasure on a lonely island.</groundspeak:short_description>
+ <groundspeak:long_description html="False">Startinhalt:
+Logbuch
+Taschenmesser
+Feuerzeug
+Ziege
+Walross
+Löwe
+
+Bitte achtet am Uferbereich auf brütende Vögel, passt auch auf eure Kinder auf.
+Betreten des Eises auf eigene Gefahr, auch hier gilt die Aufmerksamkeit den Kindern.</groundspeak:long_description>
+ <groundspeak:encoded_hints>Der Klassiker schlechthin, ein Micro im Baumstumpf, nicht originell, dafür evtl. muggelsicherer</groundspeak:encoded_hints>
+ <groundspeak:logs>
+ <groundspeak:log id="186034406">
+ <groundspeak:date>2011-09-09T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="279140">Sprenzl</groundspeak:finder>
+ <groundspeak:text encoded="False">... noch am Vorabend unserer Reise zur "10-Icons-Dy-Tour" ein paar Caches in Stuttgart gemacht und dabei sind wir auch an dieser Dose vorbeigekommen [:D] !! Vielen Dank an alle owner für die teils pfiffig gemachten Dosen !!
+
+Zum Glück hatten wir die richtige Ausrüstung im Cachemobil !!
+
+TFTC !!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="177991444">
+ <groundspeak:date>2011-08-07T07:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="742581">tmueller78</groundspeak:finder>
+ <groundspeak:text encoded="False">Mal was ganz anderes!
+Das Logbuch ist allerdings auch recht feucht, wenn auch nicht ganz so sehr wie der Weg...
+Vielen dank!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175939075">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="90014">Landmaus</groundspeak:finder>
+ <groundspeak:text encoded="False">Auf großer LB-Asperg Runde gefunden. Vor langem schon mal im Winter ohne Equipment probiert, heute hats gepasst.
+Hat Spaß gemacht in bekannter Gegend mal nach einem Jahr wieder rumzuziehen.
+Danke und bis bald im Wald
+Landmaus</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175039530">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1270295">bcas008</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute beim Dosenfischen auch hier vorbeigekommen und das Döslein auch fix bewaffnet mit Watthose gefunden. Somit stand dem Logbucheintrag nichts mehr im Weg.
+
+T4TC und fürs zeigen
+grüssle BCAS008</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175016395">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1297335">caperdonich</groundspeak:finder>
+ <groundspeak:text encoded="False">Im Team hier vorbeigekommen und nach kurzer Suche (und mit der Wathose bekleidet) konnten wir uns im Logbuch verewigen.
+TFTC und fürs Herlocken.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="175011227">
+ <groundspeak:date>2011-07-24T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2529739">Lemmer</groundspeak:finder>
+ <groundspeak:text encoded="False">Auf großer Tour heute war für alle was dabei raufklettern, reinkrabbeln, ausrätseln und natürlich viel rumsuchen und laufen laufen laufen. Sehr witzig Gummihose sei Dank, hat uns gut gefallen im Wasser zu planschen. Vielen Dank fürs erfinden und verstecken. Lemmer</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="171966035">
+ <groundspeak:date>2011-07-08T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2519606">Luftretter</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute im Team mit Kati100 hier vorbeigeschaut, kurz die Lage erkundet, beschlossen dass Boot a) zu arg auffällt und b) ohne Luftpumpe [:I] eh doof ist und dann mittels Plan B [;)] zugeschlagen. [:P]
+
+DFDC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="168208824">
+ <groundspeak:date>2011-06-20T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="1117070">Detection</groundspeak:finder>
+ <groundspeak:text encoded="False">Da SkyTrain und ich noch ein wenig Urlaub hatten, sind wir in der Gegend von Kletterdose zu Kletterdose geschlendert.
+hier war plantschen angesagt und so gesellten wir uns zu den Enten. Wegen der Küken mussten wir aufpassen nicht von den Eltern angegriffen zu werden. Ein kleiner Badespaß am frühen Morgen ohne Muggel.
+
+TFTC, Detection</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="168204217">
+ <groundspeak:date>2011-06-20T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2044578">SkyTrain</groundspeak:finder>
+ <groundspeak:text encoded="False">Zusammen mit Detection ging es durchs Stuttgarter Umlang um ein paar Sterne zu fangen.
+
+Vor einem Jahr stand ich schon mal an diesem Teich. Damals war gerade Pause und dutzende von Schulkindern tummelten sich rund um den „See“. Da wollten wir uns nicht zum Affen machen. Heute, bei leichtem Regen, war der Platz leer und der Suche nach dem Schatz stand nichts im Wege. Hat Spaß gemacht mal wieder die Gummihose durchzuspülen.
+
+Danke für den Cache
+Viele Grüße
+SkyTrain</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="162038232">
+ <groundspeak:date>2011-05-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="849709">asti_2000</groundspeak:finder>
+ <groundspeak:text encoded="False">Obwohl gegenüber gerade ein Feschtle aufgbaut wurde relativ entspannt rübergewatschelt. Erstaunlich eben und aufgeräumt der Boden. Die Enten hat's gefreut! Endlich wurde mal neue Nahrung aufgewirbelt.
+also aktiver Naturschutz!!!
+TFTC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="161952671">
+ <groundspeak:date>2011-05-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3006671">Zanderhenry</groundspeak:finder>
+ <groundspeak:text encoded="False">Mit Wathose trockenen Fußes das das Dösle erreicht.Danke für den Cache.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="159587854">
+ <groundspeak:date>2011-05-07T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="3946618">Affenpingu</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute begann unsere Cachingrunde nicht gut, es gab gleich mehrer Cache's unter anderem auch dieser, welche wir mal wieder wegen der Dorfjugend abbrechen mussten.
+
+Affenpingu</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="156042992">
+ <groundspeak:date>2011-04-21T19:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3353624">Benja.</groundspeak:finder>
+ <groundspeak:text encoded="False">Heute waren wir mit zwei Gastcachern unterwegs. Da zu dieser Zeit der See nicht zugefroren war, musste die Wathose herhalten. Damit gings auch fix auf die Schatzinsel. Jedoch wollte sich die Dose nicht so schnell zeigen. Unsere weibliche Gastcacherin wurde schließlich fündig.
+Vielen Dank für den tollen Cache, wir hatten wirklich Spaß [:D].
+
+Benja
+
+This entry was edited by Benja. on Monday, 25 April 2011 at 09:23:58 UTC.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143643778">
+ <groundspeak:date>2011-02-04T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Write note</groundspeak:type>
+ <groundspeak:finder id="2981424">BlackHawk112</groundspeak:finder>
+ <groundspeak:text encoded="False">knack, knack, knack, ach verdammt, 2 meter vor der insel musste ich schnellstmöglich und gaaaaaaaaaanz vorsichtig umdrehen.
+das eis ist bei 4,5 C° PLUS wohl doch nicht mehr so stabil und bei meinen 85 kilo hing das eis doch schon etwas durch =(
+mhmm und es war auch kein kind in der nähe das man sich kurz borgen konnte =)
+kann mir den einer sein kind kurz leihen ;-) nein scherz, dann muss ich wann anders wieder kommen</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143570318">
+ <groundspeak:date>2011-02-03T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="4034367">slowjoe66</groundspeak:finder>
+ <groundspeak:text encoded="False">Oh man das Eis hat gekracht wie die sau, aber zum Glück noch trokenen Fußes rüber gekommen.
+dfdc ist ne klasse Idee, slowjoe66</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143573844">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2983866">Julia77</groundspeak:finder>
+ <groundspeak:text encoded="False">Hält es? Hält es? Hält es? Ja, es hält!!! Und auf dem Rückweg??? - Zwar war der T5-er bei Eis nicht die große technische Herausforderung, aber der Adrenalinpegel war wegen des Knackens im Eis trotzdem hoch genug... ;-) Danke für den Cache!</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143540120">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="3949535">Alcinoo</groundspeak:finder>
+ <groundspeak:text encoded="False">Eis hat noch gut gehalten. So wars wirklich nicht zu schwer. Danke.</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143538986">
+ <groundspeak:date>2011-02-02T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2007162">Zoidberg2678</groundspeak:finder>
+ <groundspeak:text encoded="False">Knack, kanck. Aber es hat gehalten. Wir sind zu Dritt wohlbehalten rüber gekommen und genauso zurück. TFTC</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="143511134">
+ <groundspeak:date>2011-02-02T08:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2385317">Titschi</groundspeak:finder>
+ <groundspeak:text encoded="False">Huuu, Eis hielt noch :)
+
+Tftc, Titschi</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="140433464">
+ <groundspeak:date>2011-01-05T20:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="2024532">cjotle</groundspeak:finder>
+ <groundspeak:text encoded="False">Da die Kinder vom Schlitten fahren genug haben, heute mal wieder einen Cache als Frischluftprogramm angegriffen. Hier wollten wir schon mal vor 2 Jahren im Winter zuschlagen, aber da waren die Kinder noch jünger und konnten sich nicht "unauffällig" verhalten. Heute quasi zeitgleich mit Doc Brown an der Insel angekommen und gemeinsam schnell gefunden.
+Danke für den heute trockenen Fußes erreichbaren Cache.
+jotl von der cjolte-Familie</groundspeak:text>
+ </groundspeak:log>
+ </groundspeak:logs>
+ <groundspeak:travelbugs />
+ </groundspeak:cache>
+ </wpt>
+</gpx> \ No newline at end of file
diff --git a/tests/res/raw/gc1bkp3_loc.loc b/tests/res/raw/gc1bkp3_loc.loc
new file mode 100644
index 0000000..03ce48d
--- /dev/null
+++ b/tests/res/raw/gc1bkp3_loc.loc
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<loc version="1.0" src="Groundspeak">
+<waypoint>
+ <name id="GC1BKP3"><![CDATA[Die Schatzinsel / treasure island by Die unbesiegbaren Geo - Geparden]]>
+</name>
+<coord lat="48.859683" lon="9.1874"/>
+<type>Geocache</type>
+<link text="Cache Details">http://www.geocaching.com/seek/cache_details.aspx?wp=GC1BKP3</link>
+<difficulty>1</difficulty>
+<terrain>5</terrain>
+<container>2</container>
+</waypoint></loc> \ No newline at end of file
diff --git a/tests/res/raw/oc5952_gpx.gpx b/tests/res/raw/oc5952_gpx.gpx
new file mode 100644
index 0000000..a059bb2
--- /dev/null
+++ b/tests/res/raw/oc5952_gpx.gpx
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="1.0" creator="Opencaching.de - http://www.opencaching.de" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd" xmlns="http://www.topografix.com/GPX/1/0">
+ <name>Cache Listing Generated from Opencaching.de</name>
+ <desc>This is a waypoint file generated from Opencaching.de</desc>
+ <author>Opencaching.de</author>
+ <email>info@opencaching.de</email>
+ <url>http://www.opencaching.de</url>
+ <urlname>Geocaching in Deutschland, Oesterreich und der Schweiz</urlname>
+ <time>2011-09-18T09:31:09Z</time>
+ <keywords>cache, geocache, opencaching, waypoint, opencachingnetwork</keywords> <wpt lat="48.85968" lon="9.18740">
+ <time>2008-01-09T00:00:00Z</time>
+ <name>OC5952</name>
+ <desc>Die Schatzinsel / treasure island </desc>
+ <src>www.opencaching.de</src>
+ <url>http://www.opencaching.de/viewcache.php?cacheid=125931</url>
+ <urlname>Die Schatzinsel / treasure island </urlname>
+ <sym>Geocache</sym>
+ <type>Geocache|Traditional Cache</type>
+ <groundspeak:cache id="125931" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0">
+ <groundspeak:name>Die Schatzinsel / treasure island </groundspeak:name>
+ <groundspeak:placed_by>Die unbesiegbaren Geo - Geparden</groundspeak:placed_by>
+ <groundspeak:owner id="122926">Die unbesiegbaren Geo - Geparden</groundspeak:owner>
+ <groundspeak:type>Traditional Cache</groundspeak:type>
+ <groundspeak:container>Small</groundspeak:container>
+ <groundspeak:attributes>
+ </groundspeak:attributes>
+ <groundspeak:difficulty>1</groundspeak:difficulty>
+ <groundspeak:terrain>4</groundspeak:terrain>
+ <groundspeak:country>Germany</groundspeak:country>
+ <groundspeak:state>Baden-Württemberg</groundspeak:state>
+ <groundspeak:short_description html="True">Ein alter Kindheitstraum, ein Schatz auf einer unbewohnten Insel. A old dream of my childhood, a treasure on a lonely is</groundspeak:short_description>
+ <groundspeak:long_description html="True">&lt;span&gt;Startinhalt:&lt;br /&gt;
+Logbuch&lt;br /&gt;
+Taschenmesser&lt;br /&gt;
+Feuerzeug&lt;br /&gt;
+Ziege&lt;br /&gt;
+Walross&lt;br /&gt;
+L&amp;ouml;we
+&lt;p&gt;Bitte achtet am Uferbereich auf br&amp;uuml;tende V&amp;ouml;gel, passt auch auf
+eure Kinder auf.&lt;/p&gt;&lt;/span&gt;</groundspeak:long_description>
+
+ <groundspeak:logs>
+ <groundspeak:log id="408288">
+ <groundspeak:date>2009-01-12T00:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="128075">bommel-abg</groundspeak:finder>
+ <groundspeak:text encoded="False">Bei günstigen Witterungsbedingung, der See war zugefrorenen, hab ich die Chance genutzt diesen Cache zu loggen. Danke für diesen einfachen T4.&lt;br /&gt;
+bommel-abg</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="489974">
+ <groundspeak:date>2009-01-11T00:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="141464">bambuz</groundspeak:finder>
+ <groundspeak:text encoded="False">Juhu, mein erster T5. Erstaunlich leicht wenn man nur lange genug wartet. Die Wathosen hätten auch schon bereit gelegen, aber so wars dann doch leichter.&lt;br /&gt;
+&lt;br /&gt;
+TFTC&lt;br /&gt;
+&lt;br /&gt;
+Ist die Schatzdose für Kuchen oder für Käse gedacht gewesen? *grübel*</groundspeak:text>
+ </groundspeak:log>
+ <groundspeak:log id="312033">
+ <groundspeak:date>2008-04-29T00:00:00Z</groundspeak:date>
+ <groundspeak:type>Found it</groundspeak:type>
+ <groundspeak:finder id="103700">Schulze&amp;Schultze</groundspeak:finder>
+ <groundspeak:text encoded="False">Punkt 13:13 näherten sich unauffällig mehrere Personen aus verschiedenen Richtungen dem Ort des Geschehens.[8D]&lt;br /&gt;
+Unter den Augen der Owner wurde das Schlauchboot ordnungsgemäß aufgepumpt und zu Wasser gelassen. Paddel wären zwar durchaus hilfreich gewesen, aber echte Kerle lassen sich davon nicht abhalten.[:D]&lt;br /&gt;
+Sorgen um die brütenden Vögel mussten wir uns an der ausgewählten Einstiegstelle in das Gewässer nicht machen. Die Wasserqualität ist dort so anrüchig, dass sogar die Teichbewohner diese Gegend meiden.[:(]&lt;br /&gt;
+Das Schlauchboot war klein, so waren für die Schatzsuche mehrere Runden nötig. Wobei die hilfreichen Herren netterweise dafür sorgten, dass meine im Moment ohnehin angeschickerte Bandscheibe nicht weiter beansprucht wurde und ich nicht paddeln musste. Vielen Dank![:D]&lt;br /&gt;
+Von störenden Muggels blieben wir wundersamer Weise weitgehend verschont, obwohl halb Kornwestheim heute den Stadtpark frequentierte.&lt;br /&gt;
+&lt;br /&gt;
+TFTC&lt;br /&gt;
+&lt;br /&gt;
+ &lt;br /&gt;
+</groundspeak:text>
+ </groundspeak:log>
+ </groundspeak:logs>
+ <groundspeak:travelbugs>
+ </groundspeak:travelbugs>
+ </groundspeak:cache>
+ </wpt>
+</gpx> \ No newline at end of file
diff --git a/tests/res/raw/oc5952_loc.loc b/tests/res/raw/oc5952_loc.loc
new file mode 100644
index 0000000..bf2ed89
--- /dev/null
+++ b/tests/res/raw/oc5952_loc.loc
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?><loc version="1.0" src="opencaching.de">
+
+<waypoint>
+ <name id="OC5952"><![CDATA[Die Schatzinsel / treasure island by Die unbesiegbaren Geo - Geparden]]></name>
+ <coord lat="48.85968" lon="9.18740"/>
+ <type>Geocache</type>
+ <link text="Beschreibung">http://www.opencaching.de/viewcache.php?cacheid=125931</link>
+</waypoint>
+</loc> \ No newline at end of file
diff --git a/tests/src/cgeo/geocaching/test/GPXParserTest.java b/tests/src/cgeo/geocaching/test/GPXParserTest.java
new file mode 100644
index 0000000..6ec9aa6
--- /dev/null
+++ b/tests/src/cgeo/geocaching/test/GPXParserTest.java
@@ -0,0 +1,89 @@
+package cgeo.geocaching.test;
+
+import cgeo.geocaching.cgCache;
+import cgeo.geocaching.enumerations.CacheSize;
+import cgeo.geocaching.files.GPX10Parser;
+import cgeo.geocaching.geopoint.Geopoint;
+
+import android.content.res.Resources;
+import android.os.Handler;
+import android.test.InstrumentationTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+public class GPXParserTest extends InstrumentationTestCase {
+
+ public void testGPXVersion100() {
+ testGPXVersion(R.raw.gc1bkp3_gpx100);
+ }
+
+ private cgCache testGPXVersion(int resourceId) {
+ final List<cgCache> caches = readGPX(resourceId);
+ assertNotNull(caches);
+ assertEquals(1, caches.size());
+ final cgCache cache = caches.get(0);
+ assertEquals("GC1BKP3", cache.geocode);
+ assertEquals("9946f030-a514-46d8-a050-a60e92fd2e1a", cache.guid);
+ assertEquals("traditional", cache.type);
+ assertEquals(false, cache.archived);
+ assertEquals(false, cache.disabled);
+ assertEquals("Die Schatzinsel / treasure island", cache.name);
+ assertEquals("Die unbesiegbaren Geo - Geparden", cache.owner);
+ assertEquals(CacheSize.MICRO, cache.size);
+ assertEquals(1.0f, cache.difficulty.floatValue());
+ assertEquals(5.0f, cache.terrain.floatValue());
+ assertEquals("Baden-Württemberg, Germany", cache.location);
+ assertEquals("Ein alter Kindheitstraum, ein Schatz auf einer unbewohnten Insel.\nA old dream of my childhood, a treasure on a lonely island.", cache.shortdesc);
+ assertTrue(new Geopoint(48.859683, 9.1874).isEqualTo(cache.coords));
+ return cache;
+ }
+
+ public void testGPXVersion101() {
+ final cgCache cache = testGPXVersion(R.raw.gc1bkp3_gpx101);
+ assertNotNull(cache.attributes);
+ assertEquals(10, cache.attributes.size());
+ }
+
+ public void testOC() {
+ final List<cgCache> caches = readGPX(R.raw.oc5952_gpx);
+ final cgCache cache = caches.get(0);
+ assertEquals("OC5952", cache.geocode);
+ assertEquals("traditional", cache.type);
+ assertEquals(false, cache.archived);
+ assertEquals(false, cache.disabled);
+ assertEquals("Die Schatzinsel / treasure island", cache.name);
+ assertEquals("Die unbesiegbaren Geo - Geparden", cache.owner);
+ assertEquals(CacheSize.SMALL, cache.size);
+ assertEquals(1.0f, cache.difficulty.floatValue());
+ assertEquals(4.0f, cache.terrain.floatValue());
+ assertEquals("Baden-Württemberg, Germany", cache.location);
+ assertEquals("Ein alter Kindheitstraum, ein Schatz auf einer unbewohnten Insel. A old dream of my childhood, a treasure on a lonely is", cache.shortdesc);
+ assertTrue(new Geopoint(48.85968, 9.18740).isEqualTo(cache.coords));
+ }
+
+ private List<cgCache> readGPX(int resourceId) {
+ List<cgCache> caches = null;
+ final Resources res = getInstrumentation().getContext().getResources();
+ final InputStream instream = res.openRawResource(resourceId);
+ try {
+ final GPX10Parser parser = new GPX10Parser(1);
+ caches = parser.parse(instream, new Handler());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ try {
+ instream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ assertNotNull(caches);
+ assertTrue(caches.size() > 0);
+ return caches;
+ }
+
+}
diff --git a/tests/src/cgeo/geocaching/test/LocParserTest.java b/tests/src/cgeo/geocaching/test/LocParserTest.java
new file mode 100644
index 0000000..ec6d7e6
--- /dev/null
+++ b/tests/src/cgeo/geocaching/test/LocParserTest.java
@@ -0,0 +1,64 @@
+package cgeo.geocaching.test;
+
+import cgeo.geocaching.cgCoord;
+import cgeo.geocaching.enumerations.CacheSize;
+import cgeo.geocaching.files.LocParser;
+import cgeo.geocaching.geopoint.Geopoint;
+
+import android.content.res.Resources;
+import android.test.InstrumentationTestCase;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+public class LocParserTest extends InstrumentationTestCase {
+ private Map<String, cgCoord> readLoc(int resourceId) {
+ Map<String, cgCoord> caches = null;
+ final Resources res = getInstrumentation().getContext().getResources();
+ final InputStream instream = res.openRawResource(resourceId);
+ try {
+ final StringBuilder buffer = new StringBuilder();
+ int ch;
+ while ((ch = instream.read()) != -1) {
+ buffer.append((char) ch);
+ }
+ caches = LocParser.parseCoordinates(buffer.toString());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } finally {
+ try {
+ instream.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ assertNotNull(caches);
+ assertTrue(caches.size() > 0);
+ return caches;
+ }
+
+ public void testOCLoc() {
+ final Map<String, cgCoord> coords = readLoc(R.raw.oc5952_loc);
+ final cgCoord coord = coords.get("OC5952");
+ assertNotNull(coord);
+ assertEquals("OC5952", coord.geocode);
+ assertEquals("Die Schatzinsel / treasure island", coord.name);
+ assertTrue(new Geopoint(48.85968, 9.18740).isEqualTo(coord.coords));
+ }
+
+ public void testGCLoc() {
+ final Map<String, cgCoord> coords = readLoc(R.raw.gc1bkp3_loc);
+ final cgCoord coord = coords.get("GC1BKP3");
+ assertNotNull(coord);
+ assertEquals("GC1BKP3", coord.geocode);
+ assertEquals("Die Schatzinsel / treasure island", coord.name);
+ assertTrue(new Geopoint(48.859683, 9.1874).isEqualTo(coord.coords));
+ assertEquals(1.0f, coord.difficulty.floatValue());
+ assertEquals(5.0f, coord.terrain.floatValue());
+ assertEquals(CacheSize.MICRO, coord.size);
+ }
+
+}