# Android: xmlPullParser getAttributeValue gibt null zurück



## milesdavis (5. September 2013)

*Android: xmlPullParser getAttributeValue gibt null zurück*

Hi Leute,
ein erneutes Problem:

meine XML-Datei hat folgende Struktur

```
<termin tag="12" monat="2" jahr="2013" dauer="0">
[INDENT]<ort>...</ort>
<zeit von="14:00" bis="18:00"/>
<titel>...</titel>
<beschreibung>...</beschreibung>
[/INDENT]</termin>
```

Ich kann alles schön auslesen, nur komme ich nicht an die Uhrzeit ran.


```
xpp.getName()
```
 liefert "von" und "bis", 
	
	



```
xpp.getAttributeValue(null, "von")
```
 bzw. 
	
	



```
xpp.getAttributeValue(null, "bis")
```
 aber null!
Mit dem Datum funktioniert die Funktion 
	
	



```
xpp.getAttributeValue(null, "jahr")
```
 aber.

Im Anhang ist die gesamte _SitesXmlPullParser.java_




			Dieser Inhalt steht nur eingeloggten Mitgliedern zur Verfügung.
        



Hier rein Posten wäre zu unübersichtlich!
Nicht verwirren lassen wegen der Kommentare, das war ein Beispielcode, den ich mir angepasst habe.


----------



## nay (5. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*

1. es wäre besser wenn du irgendwie Zeilennummern reinbekommen hättest.

Zur Sache:

Ich denke das Problem liegt darin, dass du versuchst Attribute "von" und "bis" aus einem END_TAG auszulesen.

Edit:

2. Warum arbeitest du auf einer so niedrigen Abstraktionsebene? Ist der Code überhaupt performance-kritisch? Es gibt doch sicher einfachere Möglichkeiten ein XML auszulesen wie DOM oder so.
Außerdem würde ich nicht alles in eine Funktion packen, sondern z.B. statische Methoden für die Formatierung schreiben. Das XML ist überhaupt nicht kompliziert und du hast da schon so einen Oschi.

Schade, dass Java nicht so eine schöne native XML Integration hat wie C#. In C# würde man mit XML Linq einen Bruchteil des Codes schreiben.


----------



## milesdavis (5. September 2013)

Ich habs jetzt so gelöst, dass ich die XML-Datei umgebaut habe und die Attribute aus <zeit> in <termin> verschoben habe. Das Tag <zeit> brauch ich also nicht mehr.

In php gehts noch einfacher!

Ich hätte mir auch per webview die xml Datei über ein php-Skript auf dem Server schon als fertigen Textstring zurückgeben lassen können....
Aber wo wäre da die Herausforderung gewesen?


----------



## nay (6. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*

Ich glaube nicht, dass für PHP bessere XML Parser gibt als für Java. Ich denke, dass du dir einfach zu viel Arbeit gemacht hast, indem du dich für den XmlPullParser entschieden hast.

Am meisten überzeugt hat mich .NET, da XML dort einen hohen Stellenwert hat. Da passt das ganze Programm in 45 Zeilen:



Spoiler





```
<?xml version="1.0" encoding="utf-8" ?>
<Planer>
  <Termin>
    <Anfang>12.02.2013 14:45:02</Anfang>
    <Ende>12.02.2013 16:15:44</Ende>
    <Ort>Berlin</Ort>
    <Titel>Treffen</Titel>
    <Beschreibung>Bierchen trinken.</Beschreibung>
  </Termin>
  <!-- ... -->
</Planer>
```


```
using System;
using System.Linq;
using System.Xml.Linq;
using System.Globalization;
using System.Threading;

namespace LinqXML
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE");

            try
            {
                XDocument xml = XDocument.Load("Data.xml");
                Termin[] termine = (from termin in xml.Descendants("Termin")
                                    select new Termin
                                    {
                                        Anfang = (DateTime)termin.Element("Anfang"),
                                        Ende = (DateTime)termin.Element("Ende"),
                                        Ort = (string)termin.Element("Ort"),
                                        Titel = (string)termin.Element("Titel"),
                                        Beschreibung = (string)termin.Element("Beschreibung")
                                    }).ToArray();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString() + "\n\nBeliebige Taste drücken ...");
                Console.ReadKey();
            }
        }
    }

    class Termin
    {
        public DateTime Anfang;
        public DateTime Ende;
        public string Ort;
        public string Titel;
        public string Beschreibung;
    }
}
```


----------



## milesdavis (6. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*

und jetzt mit php


```
$pfad_zu_xml_datei = '/pfad/meineXMLDatei.xml';
if (file_exists($pfad_zu_xml_datei)) {[INDENT]$xml = simplexml_load_file($pfad_zu_xml_datei);
$anzahl_termine = $xml->count();

for ($counter=0; $counter < $anzahl_termine; $counter++){
       
//(Start-)Datum ermitteln
$datumTag = $xml->termin[$counter]->attributes()->tag;
$datumMonat = $xml->termin[$counter]->attributes()->monat;
$datumJahr = $xml->termin[$counter]->attributes()->jahr;
$datumDauer = $xml->termin[$counter]->attributes()->dauer;
       
//mehrere Tage
if($datumDauer > 0){
           [INDENT]//Enddatum bestimmen
$x = $datumJahr."-".$datumMonat."-".$datumTag;
$y = "+".$datumDauer." days";
$datumTagBis = date('d', strtotime($x.' '.$y));        // hat schon eine vorangestellte Null, wenn < 10
$datumMonatBis = date('m', strtotime($x.' '.$y));    // hat schon eine vorangestellte Null, wenn < 10
$datumJahrBis = date('Y', strtotime($x.' '.$y));
           
//ab hier: Datumsangabe zusammensetzen
           
//Datum längste Form
           
//Fall 1: Start und Ende nicht im selben Jahr
if($datumJahr != $datumJahrBis){
$datum = vorangestellte_Null($datumTag).".".vorangestellte_Null($datumMonat).".".$datumJahr." - ".vorangestellte_Null($datumTagBis).".".vorangestellte_Null($datumMonatBis).".".$datumJahrBis;}
           
//Fall 2: Anfang und Ende im selben Jahr
else if($datumJahr == $datumJahrBis){
               
//Fall 2a: monatsübergreifend
if($datumMonat != $datumMonatBis){
$datum = vorangestellte_Null($datumTag).".".vorangestellte_Null($datumMonat).". - ".$datumTagBis.".".$datumMonatBis.".".$datumJahrBis;}
               
//Fall 2b: im selben Monat
else if($datumMonat == $datumMonatBis){
$datum = vorangestellte_Null($datumTag)." - ".$datumTagBis.".".$datumMonatBis.".".$datumJahrBis;}
               
}
[/INDENT]}
           
else if($datumDauer == 0){[INDENT]//einfaches Datum
$datum = vorangestellte_Null($datumTag).".".vorangestellte_Null($datumMonat).".".$datumJahr;}
[/INDENT]//Uhrzeit angegeben
if($xml->termin[$counter]->attributes()->von == true){[INDENT]$zeit = $xml->termin[$counter]->attributes()->von." Uhr";
if($xml->termin[$counter]->attributes()->bis == true){[INDENT]$zeit = $xml->termin[$counter]->attributes()->von." - ".$xml->termin[$counter]->attributes()->bis." Uhr";}
[/INDENT]}
[/INDENT]else{[INDENT]$zeit="";}
[/INDENT]       
//Layout
echo "<div class=\"termin\" id=\"".$datumJahr."-".$datumMonat."-".$datumTag."\">[INDENT]<div class=\"z1\">".$datum."</div>
<div class=\"z2\">".$xml->termin[$counter]->ort."</div>
<div class=\"z3\">".$zeit."</div>
<div class=\"z4\">".$xml->termin[$counter]->titel."</div>
<div style=\"clear:both\"></div>
<div class=\"z5\">".$xml->termin[$counter]->beschreibung."</div>
<div style=\"clear:left\"></div>
[/INDENT]</div>";             
[/INDENT]}
```


----------



## Leandros (7. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*



nay schrieb:


> Schade, dass Java nicht so eine schöne native XML Integration hat wie C#. In C# würde man mit XML Linq einen Bruchteil des Codes schreiben.


 
XML ist nur leider ein veraltetes Format. JSON (und RESTful services) sind bereits standart und um Multiversen besser.
Abgesehen davon, das es C# nicht mal annähernd mit Java aufnehmen kann.




> Am meisten überzeugt hat mich .NET, da XML dort einen hohen Stellenwert hat.



Arbeitest du für Microsoft?


----------



## nay (7. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*



Leandros schrieb:


> XML ist nur leider ein veraltetes Format. JSON (und RESTful services) sind bereits standart und um Multiversen besser.
> Abgesehen davon, das es C# nicht mal annähernd mit Java aufnehmen kann.
> 
> 
> ...


 
Ich arbeite nicht für Microsoft. Für eine "welche Sprache ist besser"-Diskussion bin ich nicht zu haben 
Auf sachlicher Ebene könnte man in einem anderen Thread Features von C# und Java vergleichen.


----------



## Leandros (7. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*



nay schrieb:


> Ich arbeite nicht für Microsoft.


 
Warum nutzt du dann C# und .NET?


----------



## nay (7. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*



Leandros schrieb:


> Warum nutzt du dann C# und .NET?


 
Zum Entwickeln von Windows Mobile Applikationen.


----------



## milesdavis (9. September 2013)

Nochmal zurück zum Thema:

Die andere Möglichkeit wäre doch nur der SAXParser.
Aber mit diesem kam ich im ersten Moment nicht klar...


----------



## Leandros (9. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*

Wenn du mir sagst was dein Problem ist, helfe ich gerne.


----------



## milesdavis (9. September 2013)

*AW: Android: xmlPullParser getAttributeValue gibt null zurück*

Naja wie ich schon schrieb im ersten Post schrieb, dass ich eben die Uhrzeit nicht auslesen konnte.

```
<termin [datum als attribute hier]>[INDENT]<titel>...</titel>
...
<zeit von="10:00" bis="14:00" />
...
[/INDENT]</termin>
```
Jetzt hab ich ja die Zeit in 
	
	



```
<termin>
```
 gepackt als 
	
	



```
<termin [...] von="10:00" bis="14:00">
```
Warum ich aber bei der ersten Variante nicht zugreifen konnte, weiß ich nicht.
_getName()_ lieferte mir _von_ bzw. _bis_, 
_getAttributeValue()_ jedoch jeweils _null_!


----------

