Java sscanf Ersatz?

Tobias123

Lt. Commander
Registriert
Aug. 2004
Beiträge
1.196
Moin,

als erfahrener C++ Entwickler versuche ich mich gerade in Java und scheitere an einer simplen Aufgabenstellung.

Ich möchte eine XML-Datei einlesen und bestimmte Zahlenwerte zu vorgegebenen XML-Tags einlesen. So könnte eine Zeile in der XML-Datei aussehen:

<trkpt lat="28.6852600" lon="-17.7624000">

Ich möchte nun immer dann, wenn so eine Zeile auftaucht die an die Werte "lat" und "lon" kommen. In C würde ich sscanf verwenden und wäre fertig. In Java gibt es kein sscanf oder etwas ähnliches. Im Netz finde ich ca. 1000 Beiträge in denen die Leute das gleiche Problem haben. Es wird dann immer auf die "split"-Methode der Klasse "String" hingewiesen und einfach davon ausgegangen, dass alle Werte immer durch das gleiche Trennzeichen seppariert werden... passt also nicht wirklich auf mein Problem.
Wie kommt ich an die beiden double-Werte ran?

Viele Grüße
Tobias
 
Hi,

danke erst mal für die Hilfe!
Da ich meine Java-Kentnisse stärken möchte, will ich alles bewußt "per Hand" implementieren. Ziel ist es mit einem kleinen Projekt Java besser zu verstehen... Daher bin ich weiterhin an einer Lösung meines Problems interessiert :)
 
Es ist vermutlich mit Kanonen auf Spatzen geschossen, aber eine Möglichkeit wären reguläre Ausdrücke aka Regex.
 
Limit schrieb:
Es ist vermutlich mit Kanonen auf Spatzen geschossen, aber eine Möglichkeit wären reguläre Ausdrücke aka Regex.

Hi...

ja, auf die Idee bin ich auch gekommen...
Mittlerweile macht der Code das was ich will, aber irgendwie finde ich meine Lösung extrem ineffizient und umständlich:

while (raFile.getFilePointer() < raFile.length())
{
String line = raFile.readLine();

if (line.matches(".*<trkpt.*"))
{
// Found trackpoint
String[] token = line.split("\"");
System.out.println(token[1] + " " + token[3] );
double longitude = Double.parseDouble(token[1]);
double latitude = Double.parseDouble(token[3]);
}
}

Geht das nicht irgendwie "eleganter"?

Viele Grüße
Tobias
 
Naja, wenn du mehr parsen willst, sollte es bedeutend schneller sein den regulären Ausdruck erst zu "compilieren". Dafür solltest du dir vielleicht java.util.regex nochmal genauer anschauen.

Ich habe schon länger nicht mehr mit Java gearbeitet, aber so ungefähr könnte man es machen. (Hab es nicht getestet)

Code:
pattern = Pattern.compile("<trkpt lat=\"(-?\d+\.\d+)\" lon=\"(-?\d+\.\d+)\">")
for (String line; line = file.readLine(); /* nothing */) {
	matcher = pattern.matcher(line);
	if (match.find()) {
		System.out.println("lat=" + match.group(1));
		System.out.println("lon=" + match.group(2));
	}
}
 
Zuletzt bearbeitet:
Limit schrieb:
Naja, wenn du mehr parsen willst, sollte es bedeutend schneller sein den regulären Ausdruck erst zu "compilieren". Dafür solltest du dir vielleicht java.util.regex nochmal genauer anschauen.

Ich habe schon länger nicht mehr mit Java gearbeitet, aber so ungefähr könnte man es machen. (Hab es nicht getestet)

Code:
pattern = Pattern.compile("<trkpt lat=\"(-?\d+\.\d+)\" lon=\"(-?\d+\.\d+)\">")
for (String line; line = file.readLine(); /* nothing */) {
	matcher = pattern.matcher(line);
	if (match.find()) {
		System.out.println("lat=" + match.group(1));
		System.out.println("lon=" + match.group(2));
	}
}


Hi...

Intuitiv kann ich deine Lösung nachvollziehen. Allerdings frage ich mich wie ich aus der API Spezifikation auf diese Lösung kommen kann. Ich finde die Beschreibung bzgl. regulärer Ausdrücke nicht gerade sehr umfangreich. Und meine Java-Bibel (Handbuch der Java-Programmierung, ca. 1400 Seiten) schweigt sich zu diesem Thema ebenfalls aus.
Nunja... da muss ich wohl wieder den Sonntag "ver-googeln" ;)
Danke erst mal!

Gruß
Tobias
Ergänzung ()

Ok, nun habe ich das mit den regulären Ausdrücken auf dem Kasten. Aber mal ehrlich: In Java wurde alles von C/C++ weggelassen was irgendwie kompliziert werden könnte. Aber um eine formatierte Zeile einzulesen muss ich mir einen komplizierten regülären Ausdruck ausdenken... Hier ist meine funktionierende Lösung:

Pattern pattern = Pattern.compile("<trkpt +lat *= *\"(-?\\d*.\\d*)\" +lon *= *\"(-?\\d*.\\d*) *\">");
 
Zuletzt bearbeitet:
Versuch es mal mit der Javainsel. Es ist nicht nur komplett kostenlos im Internet zu lesen, sondern meiner Meinung nach auch meistens sehr verständlich geschrieben.

Zu Regex: Java ist auch eine Insel: Reguläre Ausdrücke

Was den Vergleich C++ <-> Java angeht hast du teilweise schon recht. Bei C++ gibt es viele Konstrukte, die es auf Java-Seite nicht gibt, aber häufig braucht man diese auch nicht. Im Produktiveinsatz würde man bei deinem Problem ganz sicher einen der mitgelieferten XML Parser verwenden.
 
Zuletzt bearbeitet:
Zurück
Oben