# XML einlesen



## Tino124 (3. Jan 2012)

Hallo, nun hat mich mein Problem soweit in die Verzweiflung getrieben, dass ich nun meine erste Frage in einem Forum poste.

So, und zwar habe ich ein kleines Programm geschrieben das mir bestimmte Daten aus einer XML liest und das funktioniert auch so weit. Aber da mir das zu umständlich ist für jede Anfrage erst von der URL eine XML zu erstellen, habe ich weiter gemacht und das ganze direkt über die URL gemacht, so und nun sind wir an dem Punkt meiner Verzweiflung geraten, und zwar schaffe ich es den ganzen Inhalt über die Konsole auszugeben aber Ich brauche nur einzelne Daten. In meinem ersten Programm habe ich das über die Tags mit "getTagValue" realisiert. Nun lautet meine Frage gibts so etwas ähnliches auch wenn ich das über die URL abrufe ?

Hier einmal mein Code:






```
import java.io.ByteArrayOutputStream;
	import java.io.InputStream;
	import java.net.URL;
	import java.net.URLConnection;
	import javax.swing.JOptionPane;

	
public class Reader {
	 
	public static void main(String argv[]) {
	
	 try {
	 
	 // Verbindung aufbauen
	 URL url = new URL("xy.xml");
	 URLConnection connection = url.openConnection();
	 
	 // XML Daten einlesen
	 ByteArrayOutputStream result = new ByteArrayOutputStream();
	 InputStream input = connection.getInputStream();
	 byte[] buffer = new byte[1000];
	 int amount = 0;    
	 
	 // Inhalt lesen
	 while(amount != -1){
	 
	   result.write(buffer, 0, amount);
	   amount = input.read(buffer);
	   
	   System.out.println(result.toString());
	   
	 }
	 
	 }catch(Exception e){
	 // Fehlermeldung
	 JOptionPane.showMessageDialog(null,"Es konnte keine Verbindung mit dem Internet hergestellt werden. Ist ein Proxy nötig?","Verbindungsproblem",JOptionPane.ERROR_MESSAGE);

}
}
}
```
 

                                                                                                               MfG. Tino


----------



## eRaaaa (3. Jan 2012)

Also ich verstehe das eigentliche Problem nicht? Bzw der Unterschied ist mir nicht ganz klar. 
Wie sah dein erste Ansatz aus? Was meinst du mit _"Aber da mir das zu umständlich ist für jede Anfrage erst von der URL eine XML zu erstellen"_
Laut der URL in deinem Code gibts doch bereits schon eine xml-Datei?! Gibt doch jede Menge xml-Parser der man eine URL oder einen Stream übergeben kann....

Was für Daten brauchst du denn? 
Man könnte das ziemlich leicht mit einem XML-Parser und XPath machen, oder aber ähnlich deinem Einsatz mit einem Scanner und evtl. Regex...


----------



## turtle (3. Jan 2012)

Ähnlich wie eRaaaa verstehe ich Dein Problem nicht richtig.

Zum BNispiel verstehe ich nicht, wofür hier eine URL-Verbindung gut sein soll?  Natürlich kannst Du mit XML-Daten auch arbeiten, wenn diese zum Beispiel aus einer lokalen Datei kommen!

Wie eRaaaa schon richtig angemerkt hat, kann dies über einen "üblichen" XML-Parser geschehen. Eine Variante kann zum Beispiel der Zugriff auf die XML-Daten über dom4j sein. Eine andere könnte der Zugriff auf XML via JAXB sein. 

Allen gemein ist, dass egal ist, woher die Daten kommen, also zum Beispiel von einer URL, oder von einem FileReader gelesen werden. 

Du musst uns also mehr Infos geben, was Du mit den XML-Daten eigentlich machen möchtest.


----------



## AlexSpritze (3. Jan 2012)

Ich verstehe das so, dass du über die URL nicht das komplette XML abrufen willst, sondern schon vorher sagen willst, was du aus dem XML haben willst. Das geht leider nicht so einfach. Sogar eher gar nicht.
Wenn du aber schon eine Methode hast, die dir aus einem String, der dein XML repräsentiert, die entsprechenden Informationen raussuchst, dann kannst du ja eine zweite Methode schreiben, die dir diese XML als String aus einer URL besorgt. Und schon kannst du beide Methoden verbinden, um das gewünschte zu erreichen.
Wenn ich dich falsch verstanden haben sollte, muss ich auch um mehr Informationen zu deinem Problem bitten


----------



## Tino124 (4. Jan 2012)

Also was ich eigentlich meine ist, das ich folgende URL habe : xy  und von dieser einfach direkt die Daten die ich brauche abgreife.

So nun habe ich bei meinem ersten Anlauf eine XML-Datei von der Seite erzeugt indem ich sie einfach als XML abgespeichert habe und dann mittels dem XML Parser meine gewünschten Informationen ( Linie, Ziel, Platz, HF, Abfahrt) abgerufen. Aber da ich nicht von jeder Haltestelle ( die haben alle eine eigene URL) eine XML-Datei erzeugen möchte, ist mein erster Anlauf quasi für die Tonne. Ich möchte, dass das Programm direkt anhand der URL, mir die gewünschten Informationen ausgibt. 

Hier noch einmal mein alter Quellcode, vielleicht verdeutlicht das ja nochmal den Unterschied.


```
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
 
public class ReadXMLFile {
 
	public static void main(String argv[]) {
 
	  try {
 
		File fXmlFile = new File("c:\\bsp.xml");
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(fXmlFile);
		doc.getDocumentElement().normalize();
 
		System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
		NodeList nList = doc.getElementsByTagName("Abfahrt");
		System.out.println("-----------------------");
 
		for (int temp = 0; temp < nList.getLength(); temp++) {
 
		   Node nNode = nList.item(temp);
		   if (nNode.getNodeType() == Node.ELEMENT_NODE) {
 
		      Element eElement = (Element) nNode;
 
		  System.out.println("Linie : " + getTagValue("Linie", eElement));
		  System.out.println("Ziel : " + getTagValue("Ziel", eElement));
	          System.out.println("Platz : " + getTagValue("Platz", eElement));
	          System.out.println("HF : " + getTagValue("HF", eElement));
		  System.out.println("Abfahrt in : " + getTagValue("Zeit", eElement));
 
		   }
		}
	  } catch (Exception e) {
		e.printStackTrace();
	  }
  }
 
  private static String getTagValue(String sTag, Element eElement) {
	NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
 
        Node nValue = (Node) nlList.item(0);
 
	return nValue.getNodeValue();
  }
 
}
```

Gruß Tino


----------



## ARadauer (4. Jan 2012)

> So nun habe ich bei meinem ersten Anlauf eine XML-Datei von der Seite erzeugt indem ich sie einfach als XML abgespeichert habe


 das ist schon eine xml datei... du musst sie nicht speichern  Document doc = dBuilder.parse dem kannst du auch einen InputStream übergeben. Den du dir von der URL Klasse hohlen kannst..


----------



## Tino124 (10. Jan 2012)

Ich krieg´s nicht hin, gibt nicht noch einen anderen Weg? Ich will ja Prinzipiell nur eine Verbindung mit der Seite aufbauen und mir sagen lassen wann die nächste Bahn kommt und nicht wie im Beispiel oben den ganzen Seiten Inhalt angezeigt bekommen. Eigentlich machts ja das was ich will, ich will einfach nur einen das er mir nicht den ganzen Seiteninhalt ausspuckt sondern nur bestimmte Teile. 

Also Hier noch einmal der link: xy 
Und von diesem link möchte ich z.B Zeit, Linie und Ziel ausgegeben bekommen.


----------



## eRaaaa (10. Jan 2012)

Also ich verstehe noch immer nicht dein Problem, bzw du scheinst uns nicht zu verstehen. Du musst *NICHT* die XML erst in eine Datei lokal auf deinem Rechner speichern, sondern du kannst direkt von der URL lesen.
Deine Zeile 15 kannst du löschen und Zeile 18 wie folgt abändern:

```
Document doc = dBuilder.parse(new URL("xy").openStream());
```


----------



## turtle (10. Jan 2012)

Ich schlage XPath vor.

Nachdem Du Dein gesamtes XML (in doc) hast, kannst Du mit XPath zugreifen:

```
XPath xpath = XPathFactory.newInstance().newXPath();
  XPathExpression expr = xpath.compile("//Linien/Abfahrt/Zeit ()");

  Object result = expr.evaluate(doc, XPathConstants.NODESET);
  NodeList nodes = (NodeList) result;
  for (int i = 0; i < nodes.getLength(); i++) {
 System.out.println(nodes.item(i).getNodeValue()); 
  }
```
Der Path ist wahrscheinlich nicht richtig und/oder für Dich nicht vollständig.


----------



## Tino124 (10. Jan 2012)

Achsoo... ups! Naja war schon mal ne hilfe aber wenn ich das nun durch die Zeile ersetze gibt er mir ne Fehlermeldung wegen dem .dBuilder aus.


----------



## eRaaaa (10. Jan 2012)

Tino124 hat gesagt.:


> Achsoo... ups! Naja war schon mal ne hilfe aber wenn ich das nun durch die Zeile ersetze gibt er mir ne Fehlermeldung wegen dem .dBuilder aus.



Grrr....was für eine Fehlermeldung denn? Wie sollen wir so helfen? Hast du den Import für die URL-Klasse

```
import java.net.URL;
```
eingefügt?


----------



## Tino124 (10. Jan 2012)

Ach nein, entschuldige. Ich bin völlig durch den Wind hab deine Antwort nicht richtig gelesen. Es Klappt scheinbar nun, nur bekomme ich bekomme ich nun statt meiner Ausgabe Folgendes :

java.lang.NullPointerException
	at ReadXMLFile.getTagValue(ReadXMLFile.java:46)
	at ReadXMLFile.main(ReadXMLFile.java:32)


DANKE eRaaa !


----------



## Tino124 (10. Jan 2012)

Ja den Import hab ich bereits hinzugefügt, mit der Ausgabe wills nicht so ..


----------



## eRaaaa (10. Jan 2012)

???:L
Also nochmal von vorne, ich nehme deinen o.g. Code und ändere wie folgt (wie oben beschrieben) ab:

```
import java.net.URL;

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

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

public class ReadXMLFile {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		Document doc = dBuilder.parse(new URL(
						"xy.php")
						.openStream());
		doc.getDocumentElement().normalize();

		System.out.println("Root element :"+ doc.getDocumentElement().getNodeName());
		NodeList nList = doc.getElementsByTagName("Abfahrt");
		System.out.println("-----------------------");

		for (int temp = 0; temp < nList.getLength(); temp++) {

			Node nNode = nList.item(temp);
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {

				Element eElement = (Element) nNode;

				System.out.println("Linie : " + getTagValue("Linie", eElement));
				System.out.println("Ziel : " + getTagValue("Ziel", eElement));
				System.out.println("Platz : " + getTagValue("Platz", eElement));
				System.out.println("HF : " + getTagValue("HF", eElement));
				System.out.println("Abfahrt in : "
						+ getTagValue("Zeit", eElement));

			}
		}
	}

	private static String getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
		Node nValue = (Node) nlList.item(0);
		return nValue.getNodeValue();
	}
}
```

Ausgabe

```
Root element :Linien
-----------------------
Linie : 9
Ziel : Griesheim
Platz : 2
HF : #
Abfahrt in : 6
Linie : N
Ziel : Nieder-Ramstadt
Platz : 4
HF : #
Abfahrt in : 8
Linie : O
Ziel : Brandau
Platz : 3
HF : #
Abfahrt in : 8
Linie : 2
Ziel : Hauptbahnhof
Platz : 2
HF : #
Abfahrt in : 13
Linie : R
Ziel : Nordbahnhof
Platz : 5
HF : #
Abfahrt in : 21
Linie : 9
Ziel : Griesheim
Platz : 2
HF : #
Abfahrt in : 21
Linie : NE
Ziel : Neutsch
Platz : 6
HF : #
Abfahrt in : 23
Linie : 2
Ziel : Hauptbahnhof
Platz : 2
HF : #
Abfahrt in : 28
```

:autsch:


----------



## Tino124 (10. Jan 2012)

Es Klappt! Musste nochmal ein neues Projekt anlegen, mein Eclipse hat scheinbar rumgesponnen. 

Vielen vielen Dank eRaaaa ! An dem Problem hing ich schon Wochen


----------

