Programmier Tutorial - Apps für Android entwickeln - XML Daten auslesen und anzeigen in Android

Programmier Tutorial – Teil 9: XML-Daten auslesen und anzeigen in Android


Im neunten Teil unseres großen Android™ Tutorials werden wir den String, der die XML-Aktiendaten enthält, auslesen.

Die, für uns momentan relevanten, XML-Finanzinformationen werden wir dabei in einem StringArray speichern und anschließend auf dem Android Gerät ausgeben.

In dem ersten Abschnitt dieses Tutorials werden wir das XML-Datenformat kurz vorstellen und auf die Besonderheiten der Extensible Markup Language (XML) eingehen.

Anschließend werden wir in Abschnitt zwei das XML-Format der Online-Aktiendaten analysieren und die, für uns relevanten, Finanzinformationen auswählen.

Im dritten Abschnitt erweitern wir dann unsere bisherige Android App um die Fähigkeit XML-Daten auszulesen. Als Datenquelle greifen wir auf die Online-Aktiendaten zurück, die in einem String abgelegt sind. Die ausgelesenen Finanzinformationen speichern wir danach in einem StringArray und geben sie anschließend auf dem Android Smartphone oder Tablet aus.

Nun wünschen wir euch viel Spaß bei dem neunten Teil unseres großen Android Tutorials. Los geht’s!

1. Einführung in XML (Extensible Markup Language)

Die Auszeichnungssprache XML wird zur Darstellung hierarchisch strukturierter Daten verwendet. Die Daten sind in Textform angegeben.

Die Extensible Markup Language (engl. „erweiterbare Auszeichnungssprache“, XML) ist für Menschen und Maschinen gleichermaßen verständlich und wird für den plattform- und implementationsunabhängigen Austausch von Daten zwischen Computersystemen eingesetzt, insbesondere über das Internet.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Eine XML-Datei besteht aus Textzeichen und ist auch von Menschen leicht lesbar. Binärdaten enthält ein XML-Dokument per Definition nicht.

Die Sprache XML wurde entwickelt, um mit ihr Daten beschreiben zu können. Im Gegensatz dazu steht die Sprache HTML, welche entwickelt wurde, um Daten darzustellen.

Beispiel eines XML-Dokuments

Der folgende XML-Code beschreibt das Inventar eines Buchladens:

<?xml version="1.0" encoding="UTF-8"?>
<Buchladen>
  <Buch Kategorie="Java">
    <Titel Sprache="de">Handbuch der Java Programmierung</Titel>
    <Autor>Guido Krüger / Heiko Hansen</Autor>
    <Jahr>2012</Jahr>
    <Preis>49.80</Preis>
  </Buch>
  <Buch Kategorie="Android">
    <Titel Sprache="de">Spieleprogrammierung mit Android Studio</Titel>
    <Autor>Uwe Post</Autor>
    <Jahr>2014</Jahr>
    <Preis>34.90</Preis>
  </Buch>
  <Buch Kategorie="Android">
    <Titel Sprache="de">Android - Der schnelle und einfache Einstieg</Titel>
    <Autor>Dirk Louis / Peter Müller</Autor>
    <Jahr>2014</Jahr>
    <Preis>29.99</Preis>
  </Buch>
</Buchladen> 

Die erste Zeile ist die XML Deklaration. Sie definiert die XML-Version, hier Version 1.0.

In der nächsten Zeile wird das Wurzelelement Buchladen des XML-Dokuments beschrieben. Jedes XML-Dokument muss genau ein Wurzelelement (root element) besitzen. Die Elemente eines XML-Dokuments formen eine Baumstruktur. Der Dokumentenbaum beginnt mit der Wurzel, dem Wurzelelement, und führt zu den Blättern, den Kinderelementen (child elements).

Das Wurzelelement liegt in der obersten Ebene. Unterhalb dieser Ebene können beliebig viele weitere Kinderelemente verschachtelt werden. Das Wurzelelement Buchladen besitzt die drei Buch-Kinderelemente. Diese drei Kinderelemente sind Geschwisterelemente.

Jedes dieser drei Geschwisterelemente besitzt das Attribut Kategorie. Der Attribut-Wert wird in Anführungszeichen nach dem = angegeben. Elemente können beliebig viele Attribute besitzen.

Jedes Buch-Kinderelement besitzt vier eigene Kinderelemente Titel, Autor, Jahr und Preis. Zwischen dem Start- und End-Tag eines Elements wird der Elementinhalt als reiner Text angegeben.

Das folgende Diagramm repräsentiert ein Buch aus dem oberen Beispiel XML-Dokument:

Android XML Beispiel

Darstellung eines Buch-Elements aus dem oberen XML-Dokument

In dem oberen Diagramm sind auch die Beziehungen der verschiedenen Elemente untereinander dargestellt. So ist der Buchladen das Vaterelement des Buchs und das Buch selbst ein Kindelement des Buchladens. Der Buchladen ist auch das Wurzelelement des XML-Dokuments.

Das Buch besitzt vier Kindelemente (Titel, Autor, Jahr und Preis) die untereinander Geschwisterelemente sind. Das Buch-Element besitzt das Attribut „Kategorie“, das den Wert Android enthält.

Weitere Informationen und ein sehr schönes Tutorial über XML könnt ihr bei w3schools.com finden: http://www.w3schools.com/xml/default.asp.

2. XML-Format der Online-Finanzdaten

Da wir nun die Grundlagen von XML kennen, können wir einen genaueren Blick auf das XML-Format der Online-Finanzdaten, die wir von unserem Web-Server erhalten, werfen.

Der Server liefert die Online-Aktiendaten im XML-Format. Bisher speichert unsere Android App die empfangenen Daten in einem einfachen String ab.

Der XML-String muss von uns ausgelesen werden (parsen), dazu ist es erforderlich den Aufbau des XML-Formats der Finanzdaten zu kennen.

Mit folgender Anfrage lassen wir von unserem Server simulierte Aktiendaten für die Unternehmen Daimler (DAI.DE) und BMW (BMW.DE) erzeugen:

Die Online-Aktiendaten erhalten wir in folgendem XML-Format zurück:

<query>
  <diagnostics>
    <symbols>DAI.DE,BMW.DE</symbols>
    <created>2017-11-15 20:44:25</created>
  </diagnostics>
  <results>
    <row>
      <symbol>DAI.DE</symbol>
      <name>DAI</name>
      <currency>EUR</currency>
      <exchange>GER</exchange>
      <price>44.73</price>
      <date>11/15/2017</date>
      <time>8:44pm</time>
      <change>0.281799</change>
      <percent>0.63%</percent>
      <open>44.8708995</open>
      <high>45.1245186</high>
      <low>44.3918412</low>
      <volume>7572249</volume>
    </row>
    <row>
      <symbol>BMW.DE</symbol>
      <name>BMW</name>
      <currency>EUR</currency>
      <exchange>GER</exchange>
      <price>39.72</price>
      <date>11/15/2017</date>
      <time>8:44pm</time>
      <change>0.6951</change>
      <percent>1.75%</percent>
      <open>40.06755</open>
      <high>40.69314</high>
      <low>38.88588</low>
      <volume>7014513</volume>
    </row>
  </results>
</query>

Als Nächstes werden wir die Struktur der XML-Aktiendaten analysieren. Das Wurzelelement des XML-Dokuments ist query. Es besitzt die beiden Kindelemente (child elements):

  • diagnostics
  • results

Für unsere Android Anwendung ist besonders das Element results interessant. Es enthält alle Informationen über die angefragten Finanzinstrumente, die Daten sind in den Geschwisterelementen mit dem Namen row angegeben. Für jedes angefragte Finanzinstrument (Aktie, Indize, …) ist ein entsprechendes row-Element angelegt worden.

Jedes row-Elemente besitzt die folgenden 13 Kindelemente:

  • symbol
  • name
  • currency
  • exchange
  • price
  • date
  • time
  • change
  • percent
  • open
  • high
  • low
  • volume

Davon sind momentan die Elemente symbol, name, currency, price und percent für unsere AktieHQ App von großer Bedeutung, aber auch die anderen Elemente enthalten nützliche Finanzinformationen für spätere Entwicklungsstufen unsere Anwendung.

In dem folgenden Diagramm ist das XML-Format der gelieferten Online-Finanzdaten dargestellt:

android xml aktiendaten

Darstellung des XML-Formats der simulierten Online-Finanzdaten von unserem Web-Server

Für unsere Android Anwendung ist es wichtig die hierarchische Struktur der XML-Aktiendaten zu kennen. Besonders welche Elemente welche Finanzinformationen enthalten. Im nächsten Abschnitt werden wir den XML-String parsen (auslesen) und die erhaltenen Finanzinformationen auf dem Display ausgeben.

3. Online-Aktiendaten aus dem XML-String auslesen

Android Apps Programmieren Online-Kurs

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Um XML-Dokumente in Android zu verarbeiten, sind verschiedene Standards verfügbar. Ein sehr oft verwendeter Standard ist JAXP (Java API for XML Processing).

Von JAXP werden drei verschiedene Programmierschnittstellen zur Verfügung gestellt, die XML-Dokumente interpretieren können:

  • DOM (Document Object Model) – Überführung des XML-Dokuments in eine baumartige Objektstruktur
  • SAX (Simple API for XML) – Ereignisorientierte Interpretation des XML-Dokuments
  • StAX (Streaming API for XML) – Ereignisorientierte Interpretation des XML-Dokuments

Wir werden unsere XML-Finanzdaten mit der DOM-Schnittstelle verarbeiten. Der DOM-Standard lädt beim Parsen das XML-Dokument in den Hauptspeicher und stellt es dort in Form eines Objektbaums zur Verfügung.

Die Erstellung eines solchen DOM-Objektbaums aus einem XML-Dokument lässt sich mit wenigen Zeilen Code bewerkstelligen. Daher ist DOM die optimale Methode für das Parsen von XML-Daten für unsere Android Anwendung.


Jedoch besitzt es auch einen großen Nachteil: das komplette XML-Dokument liegt im Arbeitsspeicher. Dies ist bei sehr großen XML-Dateien ein Performance-Problem. In unserem Fall jedoch nicht, da unser XML-Aktiendaten String nur von sehr geringer Größe ist.

3.1 Importieren der benötigten Klassen, Interfaces und Exceptions

Um unsere XML-Aktiendaten auszulesen, werden wir den XML-Parser des Packages javax.xml.parser verwenden. Der XML-Parser zerlegt den XML-Eingabestrom in seine grammatikalischen Bestandteile.

Um ihn nutzen zu können, müssen wir die folgenden zwei Klassen und eine Exception importieren:

AktienlisteFragment.java

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

Der XML-Parser liest unseren XML-String ein und erzeugt daraus einen Objektbaum. Damit wir den Objektbaum verwenden können, müssen wir noch einige Interfaces des Packages org.w3c.dom importieren. Unter anderem liegt darin das Interface Document, welches den eingelesenen Objektbaum repräsentiert.

Diese folgenden vier Interfaces müssen wir importieren:

AktienlisteFragment.java

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

Als vorletzten Import laden wir die Klasse InputSource aus dem Package org.xml.sax, der unseren XML-String in eine InputSource einlesen und umwandeln wird. Diese InputSource werden wir dann an den XML-Parser übergeben.

Wir müssen daher die folgende Klasse und Exception importieren:

AktienlisteFragment.java

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

Als letzten Import laden wir die StringReader-Klasse:

AktienlisteFragment.java

import java.io.StringReader;

Nachdem wir die notwendigen Importanweisungen in unser Android Projekt in die Klasse AktienlisteFragment eingefügt haben, kommen wir im nächsten Teilabschnitt zu dem eigentlichen Quellcode, durch den die XML-Aktiendaten ausgelesen (geparst) werden.

3.2 Auslesen der Online-Aktiendaten mit Hilfe eines XML-Parsers

Die XML-Aktiendaten lesen wir mit Hilfe der neuen Methode leseXmlAktiendatenAus(String xmlString) aus, der wir den XML-String mit den Online-Aktiendaten übergeben. Die Methode rufen wir am Ende des doInBackground-Tasks auf, dazu später mehr.

Die neue Methode leseXmlAktiendatenAus muss in der inneren Klasse HoleDatenTask der Klasse AktienlisteFragment definiert werden:

AktienlisteFragment.java

private String[] leseXmlAktiendatenAus(String xmlString) {

  Document doc;
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  try {
    DocumentBuilder db = dbf.newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xmlString));
    doc = db.parse(is);
  } catch (ParserConfigurationException e) {
    Log.e(LOG_TAG,"Error: " + e.getMessage());
    return null;
  } catch (SAXException e) {
    Log.e(LOG_TAG,"Error: " + e.getMessage());
    return null;
  } catch (IOException e) {
    Log.e(LOG_TAG,"Error: " + e.getMessage());
    return null;
  }

  Element xmlAktiendaten = doc.getDocumentElement();
  NodeList aktienListe = xmlAktiendaten.getElementsByTagName("row");

  int anzahlAktien = aktienListe.getLength();
  int anzahlAktienParameter = aktienListe.item(0).getChildNodes().getLength();

  String[] ausgabeArray = new String[anzahlAktien];
  String[][] alleAktienDatenArray = new String[anzahlAktien][anzahlAktienParameter];

  Node aktienParameter;
  String aktienParameterWert;
  for( int i=0; i<anzahlAktien; i++ ) {
    NodeList aktienParameterListe = aktienListe.item(i).getChildNodes();

    for (int j=0; j<anzahlAktienParameter; j++) {
      aktienParameter = aktienParameterListe.item(j);
      aktienParameterWert = aktienParameter.getFirstChild().getNodeValue();
      alleAktienDatenArray[i][j] = aktienParameterWert;
    }

    ausgabeArray[i]  = alleAktienDatenArray[i][0];                // symbol
    ausgabeArray[i] += ": " + alleAktienDatenArray[i][4];         // price
    ausgabeArray[i] += " " + alleAktienDatenArray[i][2];          // currency
    ausgabeArray[i] += " (" + alleAktienDatenArray[i][8] + ")";   // percent
    ausgabeArray[i] += " - [" + alleAktienDatenArray[i][1] + "]"; // name

    Log.v(LOG_TAG,"XML Output:" + ausgabeArray[i]);
  }

  return ausgabeArray;
}

Die Methode leseXmlAktiendatenAus untergliedert sich in zwei Teile. Der erste Teil von Zeile 3 bis 21 ist für das Parsen des XML-Strings und Erzeugen des Objektbaums mit den Aktiendaten zuständig.

Der zweite Teil von Zeile 22 bis 48 greift auf den Objektbaum zu und liest aus ihm die Aktiendaten aus. Wir verwenden dafür die Methoden getElementsByTagName und getChildNodes, mit denen wir sehr komfortabel auf die gewünschten XML-Elemente und Werte zugreifen können.

Mit den verschachtelten for-Schleifen lesen wir alle Aktiendaten unserer Aktienliste aus. Die ausgelesenen Werte speichern wir in dem zweidimensionalen Array alleAktienDatenArray ab und bauen damit den String-Array ausgabeArray zusammen.

Am Ende der Methode geben wir die ausgelesenen Finanzinformationen zurück.

3.3 Aufrufen der Methode leseXmlAktiendatenAus

Damit die XML-Aktiendaten ausgelesen werden, müssen wir noch die Methode leseXmlAktiendatenAus, von einer Stelle in unserer Anwendung aus, aufrufen. Der richtige Ort dafür ist kurz vor Ende der doInBackground-Methode unseres asynchronen Tasks.

Wir führen den Methodenaufruf bei der return-Anweisung aus und geben somit den erhaltenen String-Array sofort weiter.

AktienlisteFragment.java

protected String[] doInBackground(String... strings) {
    .
    .
    .

     return leseXmlAktiendatenAus(aktiendatenXmlString);
}

Der obere Code enthält nur die return-Anweisung mit dem Methodenaufruf. Der restliche Programmcode (durch die drei Punkte dargestellt) ist hier nicht angegeben, da er nicht verändert wurde.

Der übergebene aktiendatenXmlString enthält die von unserem Web-Server erhaltenen simulierten Aktiendaten im XML-Format. Die Methode leseXmlAktiendatenAus liest diesen XML-String aus und speichert die relevanten Finanzinformationen in einem String-Array ab. Der String-Array wird dann an die aufrufende Methode zurückgegeben.

3.4 Ausgelesene XML-Aktiendaten in ArrayAdapter einfügen

Die Methode doInBackground gibt den String-Array, der die relevanten Finanzinformationen enthält, mittels return-Anweisung weiter. Dadurch steht der String-Array jetzt als Ergebnis des asynchronen Tasks zur Verfügung und wird der Methode onPostExecute als Parameter automatisch übergeben.

Die Methode onPostExecute bleibt unverändert. Zur Übersicht ist sie hier dennoch aufgeführt:

AktienlisteFragment.java

protected void onPostExecute(String[] strings) {

    // Wir löschen den Inhalt des ArrayAdapters und fügen den neuen Inhalt ein
    // Der neue Inhalt ist der Rückgabewert von doInBackground(String...) also
    // der String-Array gefüllt mit Beispieldaten
    if (strings != null) {
        mAktienlisteAdapter.clear();
        for (String aktienString : strings) {
            mAktienlisteAdapter.add(aktienString);
        }
    }

    // Hintergrundberechnungen sind jetzt beendet, darüber informieren wir den Benutzer
    Toast.makeText(getActivity(), "Aktiendaten vollständig geladen!", 
            Toast.LENGTH_SHORT).show();
}

Die Methode onPostExecute wird am Ende des asynchronen Task automatisch aufgerufen. In ihr füllen wir den ArrayAdapter mit den ausgelesenen Online-Aktiendaten, dessen Inhalt in dem ListView eingefügt und anschließend auf unserem Android Gerät ausgegeben wird.

Da die Klasse AktienlisteFragment unserer Android App an verschiedenen Stellen verändert werden musste, kann es leicht zu Fehlern und Missverständnissen kommen. Um dies auszuschließen, solltet ihr euren Code zur Kontrolle mit der gesamten Klassendatei AktienlisteFragment.java vergleichen.

AktienlisteFragment.java (als ZIP-Datei gepackt)

4. Testen unserer Android App und Anzeigen der aktuellen Online-Aktiendaten

Dies ist ein großer Moment in der Entwicklung unserer AktieHQ App. Wir lassen das erste Mal simulierte Online-Aktiendaten auf unserem Android Smartphone oder Tablet anzeigen. Damit ist unsere Android App erstmals sinnvoll nutzbar und versorgt uns mit dem aktuellen Finanzdaten.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Damit wir unsere App auf dem Smartphone oder Tablet starten können, müssen alle Schritte von Teil 3 des Android Tutorials befolgt worden sein.

Zuerst schließen wir unser Android Gerät an den PC an und stellen eine Verbindung über die ADB (Android Debug Bridge) her. Danach klicken wir auf das Run 'app'-Symbol. Unser Android Projekt wird dadurch neu erstellt und auf dem angeschlossenen Gerät ausgeführt.

Das Run 'app'-Symbol befindet sich in der oberen Menüleiste, siehe folgende Abbildung:

android studio project avd run

Android App über das Run App-Symbol starten

Nach einigen Momenten öffnet sich der Select Deployment Target-Dialog. In ihm nehmen wir die folgenden Einstellungen vor:

  1. Das angeschlossene Android Gerät unter Connected Devices auswählen.
  2. Mit einem Klick auf den OK-Button die Installation unserer App auf das Gerät starten.
android device run app

Auswählen des angeschlossenen Android Geräts zum Aufspielen unserer App

Der Dialog schließt sich und unsere Android App wird auf das angeschlossene Gerät übertragen und installiert. Die Installation dauert nur einen kurzen Augenblick und verläuft fast unbemerkt im Hintergrund. Danach wird unsere App automatisch gestartet.

4.1 Aktuelle Aktiendaten mit unserer App abfragen und anzeigen

Zu Beginn sehen wir die alten Beipiel-Aktiendaten (mock data) in unserem ListView. Um die simulierten Online-Finanzdaten bei unserem Web-Server abzufragen, müssen wir auf den Aktualisieren-Button im Overflow Menu klicken.

Die folgende Abbildung zeigt, wie unsere Android App die Aktiendaten über das Internet abfragt:

app android xml

Mit einem Klick auf Aktualisieren werden echte Online-Aktiendaten aus dem Internet geladen

Die Online-Aktiendaten werden als Strings in dem ListView angezeigt. Wir geben für jeden Eintrag das ausgelesene Symbol, den Kurswert mit Währung, die Änderung zum Vortag in Prozent sowie den Namen des Finanzinstruments aus. Für den Moment sind diese Angaben völlig ausreichend.

Möchten wir weitere Finanzinformationen ausgeben, müssen wir diese aus dem XML-String auslesen und gesondert auf dem Android Gerät darstellen. Hierfür empfiehlt sich die Verwendung von Grafiken, wodurch die Darstellung aufgelockert wird und unsere Android Anwendung benutzerfreundlicher ist.

Was auf dem oberen Bild nicht zu sehen ist, sind die beiden anderen Kurzmitteilungen (Toasts), die über den aktuellen Status der Aktiendatenanfrage informieren. Im Bild ist nur der letzte Toast dargestellt: „Aktiendaten vollständig geladen!“.

4.2 Video – Laden von Online-Aktiendaten mit unserer Android App

Nun möchten wir unserer Anwendung auch einmal beim Holen der Online-Aktiendaten über die Schulter schauen. Dazu haben wir das folgende kurze Video erstellt, in dem die Funktion unserer App vorgestellt wird:

Zuerst sieht man die App im Startzustand. Mit einem Klick auf den Aktualisieren-Button wird der asynchrone Task HoleDatenTask im Hintergrund gestartet.

Der asynchrone Task fragt zuerst die Online-Aktiendaten bei unserem Web-Server im XML-Format ab und liest die empfangenen XML-Daten anschließend aus. Dabei werden die relevanten Finanzinformationen (Symbol, Preis, Währung, Änderung in Prozent und Name) in den ListView eingefügt und auf dem Android Gerät angezeigt.

Danach wird der asynchrone Task beendet und unsere Android App hat die Abfrage der Online-Aktiendaten für die Finanzinstrumente BMW.DE, DAI.DE und ^GDAXI beendet.

Zusammenfassung

In diesem Teil des großen Android Tutorials haben wir das Auslesen von XML-Daten kennengelernt. Die Sprache XML (Extensible Markup Language) wurde zu Beginn kurz vorgestellt und dabei auf ihre hierarchische Struktur eingegangen.

Anschließend haben wir das Format der simulierten XML-Aktiendaten analysiert und die relevanten Finanzinformationen für unsere Android App festgelegt.

Danach erweiterten wir unsere Anwendung um eine XML-Auslese-Funktion. Mit der neu definierten Methode leseXmlAktiendatenAus ist unsere App in der Lage XML-Strings auszulesen und auf bestimmte Elemente zuzugreifen. Momentan lesen wir nur fünf Parameter aus den Online-Aktiendaten aus. Es bestehen also noch viele Möglichkeiten unsere App weiter zu verbessern und nützlicher zu machen.

Abschließend haben wir die AktieHQ App auf dem Android Gerät installiert und ausgeführt. Das Video weiter oben zeigt den aktuellen Entwicklungsstand unserer Anwendung.



Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.