# XML mit DOM einlesen- Teile in Arraylist speichern



## felia (31. Mai 2010)

Hallo,

ich sitze schon einen ganzen Tag an dieser Aufgabe und komme einfach nicht mehr weiter.

Hier die Aufgabe:
Erstellen sie ein Java Programm zur Verwaltung der in XML gespeicherten Kontaktdaten. Das Programm soll folgende Funktionalitäten enthalten:
*1:* Lesen sie das in einem XML-Dokument gespeicherte Adressbuch (adressen2.xml) mit dem DOM Parser ein.

*2:*Schreiben Sie eine Methode public ArrayList<String> getAlleNamen(). Die Methode liest alle Namen aus der XML-Datei und speichert die Verkettung von Vor- und Nachname in eine ArrayList und gibt diese als Rückgabewert zurück.

*3:*Schreiben Sie eine Methode 
public ArrayList<Kontakt> getAdressenDaten(String vorname, String nachname). Die Methode liefert eine Liste von Kontakt-Objekten die mit den übergebenen Parametern übereinstimmen. 

Gegeben ist die Klasse Kontakt.java und adressen2.xml

```
public class Kontakt {

    public static enum KontaktTyp {
        privat, geschaeftlich
    }

    private String id;
    private KontaktTyp typ;
    private String Nachname;
    private String vorname;
    private String strasse;
    private String plz;
    private String ort;
    private String land;

    public Kontakt(String pId, KontaktTyp pTyp, String pNachname,
            String pVorname, String pStrasse, String pPlz, String pOrt,
            String pLand) {
        setId(pId);
        setTyp(pTyp);
        setNachname(pNachname);
        setVorname(pVorname);
        setStrasse(pStrasse);
        setPlz(pPlz);
        setOrt(pOrt);
        setLand(pLand);
    }

    public Kontakt(KontaktTyp pTyp, String pNachname, String pVorname,
            String pStrasse, String pPlz, String pOrt, String pLand) {

        this(null, pTyp, pNachname, pVorname, pStrasse, pPlz, pOrt, pLand);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public KontaktTyp getTyp() {
        return typ;
    }

    public void setTyp(KontaktTyp typ) {
        this.typ = typ;
    }

    public String getNachname() {
        return Nachname;
    }

    public void setNachname(String name) {
        this.Nachname = name;
    }

    public String getVorname() {
        return vorname;
    }

    public void setVorname(String vorname) {
        this.vorname = vorname;
    }

    public String getStrasse() {
        return strasse;
    }

    public void setStrasse(String strasse) {
        this.strasse = strasse;
    }

    public String getPlz() {
        return plz;
    }

    public void setPlz(String plz) {
        this.plz = plz;
    }

    public String getLand() {
        return land;
    }

    public void setLand(String land) {
        this.land = land;
    }

    public String getOrt() {
        return ort;
    }

    public void setOrt(String ort) {
        this.ort = ort;
    }

	
}
```


```
<?xml version="1.0" ?> 
- <Adressbuch>
- <Kontakt typ="privat">
- <Name>
  <Vorname>Max</Vorname> 
  <Nachname>Mustermann</Nachname> 
  </Name>
- <Adresse>
  <Strasse>Musterstrasse 10</Strasse> 
  <PLZ>10199</PLZ> 
  <Ort>Berlin</Ort> 
  <Land>Deutschland</Land> 
  </Adresse>
  </Kontakt>
- <Kontakt typ="privat">
- <Name>
  <Vorname>Sandra</Vorname> 
  <Nachname>Tester</Nachname> 
  </Name>
+ <Adresse>
  <Strasse>Stallvagen 3</Strasse> 
  <PLZ>35761</PLZ> 
  <Ort>Alvesta</Ort> 
  <Land>Schweden</Land> 
  </Adresse>
  </Kontakt>
- <Kontakt typ="privat">
- <Name>
  <Vorname>Karl</Vorname> 
  <Nachname>Leister</Nachname> 
  </Name>
- <Adresse>
  <Strasse>Hauptstrasse 3</Strasse> 
  <PLZ>03572</PLZ> 
  <Ort>Dresden</Ort> 
  <Land>Deutschland</Land> 
  </Adresse>
  </Kontakt>
- <Kontakt typ="geschaeftlich">
- <Name>
  <Vorname>Bernd</Vorname> 
  <Nachname>Business</Nachname> 
  </Name>
- <Adresse>
  <Strasse>Neuer Weg 30</Strasse> 
  <PLZ>12055</PLZ> 
  <Ort>Berlin</Ort> 
  <Land>Deutschland</Land> 
  </Adresse>
  </Kontakt>
- <Kontakt typ="geschaeftlich">
- <Name>
  <Vorname>Moritz</Vorname> 
  <Nachname>Makler</Nachname> 
  </Name>
- <Adresse>
  <Strasse>Lindenstrasse 3</Strasse> 
  <PLZ>54762</PLZ> 
  <Ort>Frankfurt am Main</Ort> 
  <Land>Deutschland</Land> 
  </Adresse>
  </Kontakt>
  </Adressbuch>
```

Hier noch meine Anfänge:

```
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;

/**
 * 
 * 
 * 
 */
public class XMLAdressbuch {
    // Pfad und Name der XML Datei die ausgegeben werden soll
    private static String XMLDateiName = "./src/adressen2.xml";
    private static String vorname, nachname;
    // XML Werte Konstanten
  
    private static ArrayList<String> liste;
	private static ArrayList<Kontakt> liste2;
    
    
    /**
     * Main Methode.
     * 
     * @param args 
     * ohne
     */

	public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        // Uebergebene XML-Datei parsen
        Document dokument = builder.parse(new File(XMLDateiName));
        // Wurzelelement Adressbuch holen
        Element abuchElement = dokument.getDocumentElement();
        
        
        getAlleNamen(dokument);
        getAdressenDaten(vorname, nachname, dokument);
     
        // DOM Baum durchlaufen und ausgeben
        traversieren(dokument.getDocumentElement(), "");
    }

    /**
     * Methode zum Durchlaufen und Ausgeben des DOM Baums.
     * 
     * @param e aktuelles Element
     * @param ebene String für die Einrueckung der Ebenen
     */
    private static void traversieren(Element e, String ebene) {
        System.out.println(ebene + e.getNodeName());
        // Kindelemente des uebergebenen Elements ermitteln
        NodeList children = e.getChildNodes();
        for (int i = 0; i < children.getLength(); i++) {
            Node knoten = children.item(i);
            // Knoten ist ein ELEMENT_NODE
            if (knoten.getNodeType() == Node.ELEMENT_NODE)
                // Rekursiver Aufruf von traversieren für aktuelles Element
                traversieren((Element) knoten, ebene + " ");
            // Knoten ist ein TEXT_NODE
            else if (knoten.getNodeType() == Node.TEXT_NODE) {
                String inhalt = knoten.getTextContent();
                if (inhalt.trim().length() > 0) // leerer Inhalt?
                    System.out.println(ebene + " :" + inhalt);
            } else
                // kein ELEMENT_NODE, kein TEXT_NODE
                System.out.println(ebene + knoten);
        }
    }
	
	
	public static ArrayList<String> getAlleNamen(Document dokument){   
     // Alle Kindelemente mit dem Namen Vornamen einsammeln
        NodeList kontaktNodes = dokument.getElementsByTagName("Kontakt");
        liste = new ArrayList<String>(kontaktNodes.getLength());
        for (int i=0; i<kontaktNodes.getLength(); i++) {
        // Node nach Element casten
        Element kontaktElement = (Element) kontaktNodes.item(i);
        // Neue Instanz von Person anlegen
        Kontakt person = new Kontakt(null, XMLDateiName, XMLDateiName, XMLDateiName, XMLDateiName, XMLDateiName, XMLDateiName);
        // Kindelemente Vorname suchen, den Textinhalt als Vorname nehmen
        NodeList node1 = kontaktElement.getElementsByTagName("Vorname");
        person.setVorname(node1.item(0).getTextContent());
        // Analog für nachname
        NodeList node2 = kontaktElement.getElementsByTagName("Nachname");
        person.setNachname(node2.item(0).getTextContent());
        
        vorname=person.getVorname();
        nachname=person.getNachname();
        liste.add(vorname+" "+nachname);
    
        }
        
        // Kontroll Ausgabe der Liste auf der Konsole
        System.out.println("*** Alle Namen ***");
        System.out.println(liste);
		return liste;
	}
	
	
	public static ArrayList<Kontakt> getAdressenDaten(String vorname, String nachname, Document children){
		
		// Alle Kindelemente mit dem Namen Vornamen einsammeln
        
        liste2 = new ArrayList<Kontakt>(liste.size());
        for (int i=0; i<liste.size(); i++) {
        
        	// Neue Instanz von Person anlegen
        Kontakt person = new Kontakt(null, pNachname, XMLDateiName, XMLDateiName, XMLDateiName, XMLDateiName, XMLDateiName);
        // Kindelemente Vorname suchen, den Textinhalt als Vorname nehmen
        System.out.print(person.getStrasse());
        
        }
		return liste2;
	}}
```

Ich bin auch schon völlig irritiert, was diesen DOM Parser betrifft.
Kann man wie gefordert auf die ausgelesenen Daten der XML erneut zugreifen ohne alles wieder aufzurufen? Ich habe nur versucht mich da durchzuhangeln, aber alle google Sachen haben mir die Frage nicht beantworten können.
Im Grunde weiss ich nicht wie ich damit richtig umgehen soll und ob ich die Aufgabe richtig verstehe.
Wie lese ich für 1: alle XML Daten-Knoten samt Inhalt aus. Stimmt das, was ich in der Main gemacht habe so?
Zu 2: Hier soll ich doch die Namen aus Vorname + Nachname in einer ArrayList speichern.
Zu 3: Hier soll ich vermutlich die ArrayList mit den restlichen Adressdaten in einer anderen Liste abspeichern, aber sicher bin ich mir da nicht!?! Was meint ihr?
Vor allem wozu brauche ich nun diese Kontakt.java

Bitte helft mir! Ich bin am Verzweifeln!

Viele Grüße,
felia


----------



## felia (1. Jun 2010)

So, ich habe mich nochmal rangesetzt und die Punkte 1+2 neu bearbeitet.
Ich komme aber immer noch kein bisschen weiter, was den Punkt 3 betrifft.

Helft mir mal auf die Sprünge, wenn ihr versteht, was ich da machen muss.


```
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.util.ArrayList;


/**
 * 
 * 
 * 
 */
public class XMLAdressbuch {
    // Pfad und Name der XML Datei die ausgegeben werden soll
    private static String XMLDateiName = "./src/adressen2.xml";
    private static ArrayList<String> liste;
	private static ArrayList<Kontakt> liste2;
    
    
    /**
     * Main Methode.
     * 
     * @param args 
     * ohne
     * 
     */

	public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        // Uebergebene XML-Datei parsen
        Document dokument = builder.parse(new File(XMLDateiName));
            
    }

    /**
     * Methode zum Speichern der Vornamen und Nachnamen 
     *   als Name in eine Arrayliste
     * @param dokument 
     */
    public ArrayList<String> getAlleNamen(Document dokument) {
    	NodeList vorname= dokument.getElementsByTagName("Vorname");      
        NodeList nachname= dokument.getElementsByTagName("Nachname");
        liste = new ArrayList<String>(vorname.getLength());
        for (int i=0; i<vorname.getLength();i++){
        liste.add(vorname.item(i).getTextContent()+ " "+nachname.item(i).getTextContent());
        }
        System.out.print(liste);   
        return liste;
    }
	
	
	}
```


----------



## felia (1. Jun 2010)

Und noch eine endgültige Version der Aufgabe.

Es wäre super, wenn ihr mal schaut, ob es besser zu lösen geht.
Ich bin noch neu in der Programmierung.


```
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import java.util.ArrayList;

/**
 * 
 * 
 * 
 */
public class XMLAdressbuch {
    // Pfad und Name der XML Datei die ausgegeben werden soll
    private static String XMLDateiName = "./src/adressen2.xml";
    private static ArrayList<String> liste;
	private static ArrayList<Kontakt> liste2;
    private static String Vorname, Nachname;
	
    
    /**
     * Main Methode.
     * 
     * @param args 
     * ohne
     * 
     */

	public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        // Uebergebene XML-Datei parsen
        Document dokument = builder.parse(new File(XMLDateiName));
        getAlleNamen(dokument);
        getAdressenDaten(Vorname, Nachname, dokument);
    }

    /**
     * Methode zum Speichern der Vornamen und Nachnamen 
     *   als Name in eine Arrayliste
     * @param dokument 
     */
    public static ArrayList<String> getAlleNamen(Document dokument) {
    	NodeList vorname= dokument.getElementsByTagName("Vorname");      
        NodeList nachname= dokument.getElementsByTagName("Nachname");
        liste = new ArrayList<String>(vorname.getLength());
        for (int i=0; i<vorname.getLength();i++){
        	String Vorname=vorname.item(i).getTextContent();
        	String Nachname=nachname.item(i).getTextContent();
        liste.add(Vorname+" " +Nachname);
            	
        }
           
        return liste;
    }
    public static ArrayList<Kontakt> getAdressenDaten(String Vorname, String Nachname, Document dokument){
    	NodeList vorname= dokument.getElementsByTagName("Vorname");      
        NodeList nachname= dokument.getElementsByTagName("Nachname");
    	NodeList strasse= dokument.getElementsByTagName("Strasse");
    	NodeList plz=dokument.getElementsByTagName("Plz");
    	NodeList ort=dokument.getElementsByTagName("Ort");
    	NodeList land=dokument.getElementsByTagName("Land");
    	liste2 = new ArrayList<Kontakt>(liste.size());
    	for (int i =0;i<liste.size();i++){
    	String pVorname=vorname.item(i).getTextContent();
        String pNachname=nachname.item(i).getTextContent();  	   	
    	String pPlz=plz.item(i).getTextContent();
    	String pOrt=ort.item(i).getTextContent();
    	String pLand=land.item(i).getTextContent();
    	String pStrasse = strasse.item(i).getTextContent();
    	
    	Kontakt k= new Kontakt(null, pNachname, pVorname, pStrasse, pPlz, pOrt, pLand);
    	k.setVorname(pVorname);
    	k.setNachname(pNachname);
    	k.setStrasse(pStrasse);
    	k.setPlz(pPlz);
    	k.setOrt(pOrt);
    	k.setLand(pLand);
        liste2.add(k);
        }
       
        System.out.println(liste2);
    	return liste2;
    	    	
    }
	}
```


----------



## oldshoe (6. Jun 2010)

Ich habs nur mal überflogen. Was funktioniert denn noch nicht?

Auf jeden Fall kannst du schon mal folgendes bei getAdressenDaten ändern von:

```
Kontakt k= new Kontakt(null, pNachname, pVorname, pStrasse, pPlz, pOrt, pLand);
        k.setVorname(pVorname);
        k.setNachname(pNachname);
        k.setStrasse(pStrasse);
        k.setPlz(pPlz);
        k.setOrt(pOrt);
        k.setLand(pLand);
```
nach

```
Kontakt k= new Kontakt(null, pNachname, pVorname, pStrasse, pPlz, pOrt, pLand);
```
denn du legst ja schon einen neuen Kontakt an und übergibst dabei auch schon gleich den vornamen usw. Dafür ist nämlich dieser Konstruktor (new Kontakt() ) bei Kontakt, damit man sich das manuelle set jedesmal sparen kann.

Ansonsten scheint das schon soweit deiner Aufgabenstellung zu entsprechen. Die Ausgabe mit system.out deiner Listen ist ja nirgendswo gefordert, also würde ich das erstmal auch weglassen. Du könntest das dann auch schöner in der main ausgeben lassen. Einfach noch ne Schleife in der die Listen durchlaufen werden, z.B.: 
	
	
	
	





```
List<String>namensListe= getAlleNamen(dokument);
for (String name:namensListe){
system.out.println(name);
}
```


----------



## felia (7. Jun 2010)

Vielen Dank oldshoe!

Die print-Ausgabe habe ich schon rausgenommen, das war für mich einfach nur zur Kontrolle und hab es hier vergessen schon wegzulöschen. ;-)

Das mit den k.set... mit diesen ganzen Konstruktoren und zwischen Klassen hin- und herspringen muss ich mir wohl wirklich nochmal genauer anschauen - Theorie.
Doppeltes Übergeben ist nicht so wirklich sinnvoll! Danke!
Mal sehen, was mein Prof dazu sagt. Ich vermute, genau das gleiche... ;-)

LG,
felia


----------

