# XML File aus Internet korrekt mit absätzen formatiert abspeichern



## ndrizza (13. Jan 2011)

Hallo zusammen,

ich habe folgendes Java Programm:


```
package Weather;

import java.beans.XMLDecoder;
import java.io.*;
import java.net.*;

public class Filesaver{
public static void main(String args[]) throws IOException{

java.io.BufferedInputStream in = new java.io.BufferedInputStream(new
java.net.URL("http://www.google.com/ig/api?weather=Zuerich").openStream());

java.io.FileOutputStream fos = new java.io.FileOutputStream("wetter.xml");
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos);

byte[] data = new byte[1024];
int x=0;
while((x=in.read(data,0,1024))>=0){
      bout.write(data,0,x);
      }
      bout.close();
      in.close();
      }

}
```

Wenn ich den XML Stream speichere dann kommt er so raus:
[XML]<?xml version="1.0"?><xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" ><forecast_information><city data="Zürich District, Canton of Zürich"/><postal_code data="Zuerich"/><latitude_e6 data=""/><longitude_e6 data=""/><forecast_date data="2011-01-13"/><current_date_time data="2011-01-13 12:20:00 +0000"/><unit_system data="US"/></forecast_information><current_conditions><condition data="Mostly Cloudy"/><temp_f data="50"/><temp_c data="10"/><humidity data="Humidity: 87%"/><icon data="/ig/images/weather/mostly_cloudy.gif"/><wind_condition data="Wind: SW at 13 mph"/></current_conditions><forecast_conditions><day_of_week data="Thu"/><low data="41"/><high data="51"/><icon data="/ig/images/weather/chance_of_rain.gif"/><condition data="Chance of Rain"/></forecast_conditions><forecast_conditions><day_of_week data="Fri"/><low data="41"/><high data="50"/><icon data="/ig/images/weather/sunny.gif"/><condition data="Clear"/></forecast_conditions><forecast_conditions><day_of_week data="Sat"/><low data="39"/><high data="50"/><icon data="/ig/images/weather/mostly_sunny.gif"/><condition data="Mostly Sunny"/></forecast_conditions><forecast_conditions><day_of_week data="Sun"/><low data="39"/><high data="48"/><icon data="/ig/images/weather/sunny.gif"/><condition data="Clear"/></forecast_conditions></weather></xml_api_reply>[/XML]

Er sollte aber beim Speichern so formatiert werden:
[XML]<?xml version="1.0"?>
<xml_api_reply version="1">
  <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" >
    <forecast_information>
      <city data="Zürich District, Canton of Zürich"/>
      <postal_code data="Zuerich"/>
      <latitude_e6 data=""/>
      <longitude_e6 data=""/>
      <forecast_date data="2011-01-12"/>
      <current_date_time data="2011-01-12 17:20:00 +0000"/>
      <unit_system data="US"/>
    </forecast_information>
    <current_conditions>
      <condition data="Light rain"/>
      <temp_f data="43"/>
      <temp_c data="6"/>
      <humidity data="Humidity: 81%"/>
      <icon data="/ig/images/weather/mist.gif"/>
      <wind_condition data="Wind: S at 9 mph"/>
    </current_conditions>
    <forecast_conditions>
      <day_of_week data="Wed"/>
      <low data="41"/>
      <high data="46"/>
      <icon data="/ig/images/weather/chance_of_rain.gif"/>
      <condition data="Chance of Rain"/>
    </forecast_conditions>
    <forecast_conditions>
      <day_of_week data="Thu"/>
      <low data="41"/>
      <high data="51"/>
      <icon data="/ig/images/weather/chance_of_rain.gif"/>
      <condition data="Chance of Rain"/>
    </forecast_conditions>
    <forecast_conditions>
      <day_of_week data="Fri"/>
      <low data="39"/>
      <high data="48"/>
      <icon data="/ig/images/weather/sunny.gif"/>
      <condition data="Clear"/>
    </forecast_conditions>
    <forecast_conditions>
      <day_of_week data="Sat"/>
      <low data="39"/>
      <high data="50"/>
      <icon data="/ig/images/weather/chance_of_rain.gif"/>
      <condition data="Chance of Rain"/>
    </forecast_conditions>
  </weather>
</xml_api_reply>
[/XML]

Wäre froh, wenn mir jemand den Java Code geben könnte um das XML File wie in der 2 Darstellung mit absätzen zu speichern.

Gruss.


----------



## Marco13 (13. Jan 2011)

Eine einfachere Möglichkeit, als das ganze zu parsen und wieder auszugeben, wüßte ich jetzt nicht...

```
// Marco13 for http://www.java-forum.org/xml-co/111911-xml-file-internet-korrekt-absaetzen-formatiert-abspeichern.html

import java.io.*;
import java.nio.charset.Charset;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.*;
import org.xml.sax.SAXException;

public class XMLFormatTest
{
    public static void main(String args[])
    {
        String s =
            "<?xml version=\"1.0\"?><xml_api_reply version=\"1\">"+
            "<weather module_id=\"0\" tab_id=\"0\" mobile_row=\"0\" "+
            "mobile_zipped=\"1\" row=\"0\" section=\"0\" >"+
            "<forecast_information><city data=\"Zürich District,"+
            " Canton of Zürich\"/><postal_code data=\"Zuerich\"/>"+
            "<latitude_e6 data=\"\"/><longitude_e6 data=\"\"/>"+
            "<forecast_date data=\"2011-01-13\"/><current_date_time"+
            " data=\"2011-01-13 12:20:00 +0000\"/><unit_system data=\"US\"/>"+
            "</forecast_information><current_conditions><condition "+
            "data=\"Mostly Cloudy\"/><temp_f data=\"50\"/><temp_c "+
            "data=\"10\"/><humidity data=\"Humidity: 87%\"/><icon "+
            "data=\"/ig/images/weather/mostly_cloudy.gif\"/>"+
            "<wind_condition data=\"Wind: SW at 13 mph\"/>"+
            "</current_conditions><forecast_conditions><day_of_week"+
            " data=\"Thu\"/><low data=\"41\"/><high data=\"51\"/>"+
            "<icon data=\"/ig/images/weather/chance_of_rain.gif\"/>"+
            "<condition data=\"Chance of Rain\"/></forecast_conditions>"+
            "<forecast_conditions><day_of_week data=\"Fri\"/><low"+
            " data=\"41\"/><high data=\"50\"/>"+
            "<icon data=\"/ig/images/weather/sunny.gif\"/><condition"+
            " data=\"Clear\"/></forecast_conditions><forecast_conditions>"+
            "<day_of_week data=\"Sat\"/><low data=\"39\"/><high "+
            "data=\"50\"/><icon data=\"/ig/images/weather/mostly_sunny."+
            "gif\"/><condition data=\"Mostly Sunny\"/></forecast_conditions>"+
            "<forecast_conditions><day_of_week data=\"Sun\"/><low "+
            "data=\"39\"/><high data=\"48\"/><icon data=\"/ig/images/"+
            "weather/sunny.gif\"/><condition data=\"Clear\"/>"+
            "</forecast_conditions></weather></xml_api_reply>";

        String t = format(s);
        System.out.println(format(t));
    }

    private static String format(String s)
    {
        try
        {
            Charset charset = Charset.forName("UTF-8");
            Node node = read(new ByteArrayInputStream(s.getBytes(charset)));
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            write(node, outputStream);
            outputStream.close();
            String t = new String(outputStream.toByteArray(), charset);
            return t;
        }
        catch (ParserConfigurationException e)
        {
            throw new IllegalArgumentException("Failed to format string", e);
        }
        catch (SAXException e)
        {
            throw new IllegalArgumentException("Failed to format string", e);
        }
        catch (IOException e)
        {
            throw new IllegalArgumentException("Failed to format string", e);
        }
        catch (TransformerException e)
        {
            throw new IllegalArgumentException("Failed to format string", e);
        }
    }

    private static Node read(InputStream inputStream)
        throws ParserConfigurationException, SAXException, IOException
    {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
        Document document = documentBuilder.parse(inputStream);
        return document;
    }

    private static void write(Node node, OutputStream outputStream)
        throws TransformerException
    {
        TransformerFactory transformerFactory =
            TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(
            "{http://xml.apache.org/xslt}indent-amount", "4");
        Source source = new DOMSource(node);
        Result result = new StreamResult(outputStream);
        transformer.transform(source, result);
    }
}
```


----------



## ndrizza (13. Jan 2011)

Vielen Dank für deine Hilfe!
Es hat mich weitergebracht:

Hier der Code wo ich es implementieren konnte:

Ein nützliches Beispiel um das Aktuelle Wetter anzuzeigen:
(wahrscheinlich könnte man es mit viel weniger Umwegen hinbekommen, aber ich bin froh klappts.)

Grüsse


```
package Weather;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class WeatherDisplayer {

	public static void main(String[] args) throws IOException {

		// ************* XML als TXT speichern ********************************
		java.io.BufferedInputStream in = new java.io.BufferedInputStream(
				new java.net.URL("http://www.google.com/ig/api?weather=Zuerich")
						.openStream());

		java.io.FileOutputStream fos = new java.io.FileOutputStream(
				"wetter.txt");
		java.io.BufferedOutputStream bout = new BufferedOutputStream(fos);

		byte[] data = new byte[1024];
		int x = 0;
		while ((x = in.read(data, 0, 1024)) >= 0) {
			bout.write(data, 0, x);
		}
		bout.close();
		in.close();
		// ************* ENDE: XML als TXT speichern **************************

		// ************* XML in TXT FILE formatieren **************************
		String s = deserializeString(new File("wetter.txt"));
		format(s);
		// ************* ENDE: XML in TXT FILE formatieren ********************

		// ************* FORMATIERTES XML AUSLESEN ****************************
		try {
			File file = new File("wetter.xml");
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();

			NodeList nodes = (NodeList) doc
					.getElementsByTagName("current_conditions");

			for (int i = 0; i < nodes.getLength(); i++) {
				Node node = nodes.item(i);

				if (node.getNodeType() != Node.ELEMENT_NODE)
					continue;

				NodeList children = nodes.item(0).getChildNodes();

				for (int o = 0; o < children.getLength(); o++) {
					Node child = children.item(o);
					if (child.getNodeType() != Node.ELEMENT_NODE)
						continue;
					if (!"condition".equals(child.getNodeName()))
						continue;

					String data2 = ((Element) child).getAttribute("data");
					System.out.println(data2);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		// ************* ENDE: FORMATIERTES XML AUSLESEN **********************
	}

	// ############### METHODEN ZUM FORMATIEREN ###############################
	private static void format(String s) {
		try {
			Charset charset = Charset.forName("UTF-8");
			Node node = read(new ByteArrayInputStream(s.getBytes(charset)));
			FileOutputStream outputStream = new FileOutputStream("wetter.xml");
			write(node, outputStream);
			outputStream.close();
		} catch (ParserConfigurationException e) {
			throw new IllegalArgumentException("Failed to format string", e);
		} catch (SAXException e) {
			throw new IllegalArgumentException("Failed to format string", e);
		} catch (IOException e) {
			throw new IllegalArgumentException("Failed to format string", e);
		} catch (TransformerException e) {
			throw new IllegalArgumentException("Failed to format string", e);
		}
	}

	private static Node read(InputStream inputStream)
			throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
		Document document = documentBuilder.parse(inputStream);
		return document;
	}

	private static void write(Node node, OutputStream outputStream)
			throws TransformerException {
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.setOutputProperty(
				"{http://xml.apache.org/xslt}indent-amount", "4");
		Source source = new DOMSource(node);
		Result result = new StreamResult(outputStream);
		transformer.transform(source, result);
	}

	public static String deserializeString(File file) throws IOException {
		int len;
		char[] chr = new char[4096];
		final StringBuffer buffer = new StringBuffer();
		final FileReader reader = new FileReader(file);
		try {
			while ((len = reader.read(chr)) > 0) {
				buffer.append(chr, 0, len);
			}
		} finally {
			reader.close();
		}
		return buffer.toString();
	}
	// ######### ENDE: METHODEN ZUM FORMATIEREN ###############################

}
```


----------



## JohannisderKaeufer (14. Jan 2011)

Ein wie ich finde schönes Beispiel mit einem org.apache.xml.serialize.XMLSerializer und dem passenden org.apache.xml.serialize.OutputFormat gibt es auf der Java Ranch

How To Pretty Print Xml With Java at JavaRanch

Den Weg über die TransformerFactory find ich irgendwie wie von hinten durch die Brust ins Auge.


----------



## Marco13 (14. Jan 2011)

Ist der Apache Serializer teil der Standard-API? Ich glaub' nicht...


----------



## ndrizza (14. Jan 2011)

ja danke für den Tipp mit dem Apache, ich hatte den auch gesehen, aber ich konnte irgendwie nie die api installieren. muss aber auch gut sein.

Statt das ganze zwischenzuspeichern in einem .txt, dann in einem .xml wäre es mir am liebsten gewesen alles über streams oder strings zu machen(ohne ein file zu speichern), aber ich weiss nicht wie es geht.

es ist aber nicht nötig, dass das jetzt jemand versucht. es ist nicht so wichtig.

Ich werde es nochmals versuchen die Apache API zu installieren, die scheint viel gebraucht zu sein.

Gruss.


----------



## Marco13 (14. Jan 2011)

Das mit dem File hatte ich nicht gesehen - sieht murksig aus. Allgemein sollte man überall da, wo ein (File)OutputStream verwendet wird, auch einen ByteArrayOutputStream verwenden können, von dem man sich dann die Daten als byte[] array abholen kann (und sei es nur, um sie in einen ByteArrayInputStream zu packen, von dem man sie dann wieder genauso lesen kann, wie aus einem FileInputStream)


----------



## JohannisderKaeufer (16. Feb 2011)

Marco13 hat gesagt.:


> Ist der Apache Serializer teil der Standard-API? Ich glaub' nicht...



Die import-Statements aus dem von mir Verlinkten Beispiel, beziehen sich auf die Apache Implementierung.


```
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
```

Sollten aber so auch im JDK vorhanden sein. Bei mir ist das so der Fall und ich habe in der Hinsicht nichts extra installieren müssen.

Insbesondere nutzt doch auch dein Beispiel apache
[JAVA=99]            "{http://xml.apache.org/xslt}indent-amount", "4");
[/code]


----------



## Marco13 (16. Feb 2011)

Ja, aber das "...xml.*internal*" ist wohl das gefährliche. Es ist nicht garantiert, dass das im nächsten JDK noch vorhanden ist. 

Kleine Anekdote dazu: Ich hatte (habe) mit einem Programm zu tun, wo jemand mit dem JDK 1.4 ein bißchen XML-Gewurschtel zusammengestümpert hat. Beim JDK 1.4 wurde für XML noch ... eine bestimmte Implementierung verwendet, "Xerces" oder so? Bei dieser Implementierung war die "toString"-Methode der Implementierung vom XML 'Node' zufällig(!) so überschrieben, dass sie einen hübsch formatierten XML-String des Knotens geliefert hat. Dann kam Java 1.5. Dort war die Implementierung eine andere, und toString hat NICHT mehr einen XML-String geliefert. Natürlich ging in diesem grandiosen Programm dann GAR nichts mehr, und offenbar waren die verantwortlichen zu ... (hier ein paar diskreditierend klingende Worte einsetzen) ... um den Fehler genauer zu analysieren. Das hatte zur Folge, dass der Wechsel von 1.4 auf 1.5 lange, lange verschoben wurde - bis ich mal eine "machEinenXMLStringAusEinemNode"-Methode implementiert habe. Viel komplizierter und "manueller" als die mit dem Transformer, aber ... zumindest konnte dann auf 1.5 gewechselt werden...


----------



## slawaweis (17. Feb 2011)

in dem Artikel:

Pretty-Print XML from a DOM

ist "Method 2: DOM Level 3 Load and Save" beschrieben, was das neue unabhängige Formatieren von XML Dokumenten im Sinne von W3C sein soll. Funktioniert aber erst seit Java 6.

Slawa


----------



## Olli80 (30. Mai 2011)

Hallo,

ich habe lange gesucht und endlich genau so eine Funktion gefunden, die ich verzweifelt suche.

Finde ich echt super, da ich die Wetterdaten zur weiteren Verwendung in meiner gebauten Hausautomation brauche.

Leider habe ich absolut keine Ahnung von Java und derren Programmierung ;(

Ich habe mir mal die SDK runter geladen und war sogar in der Lage den Code zu kompilieren. Jedoch bekomme ich beim ausführen der .jar datei immer folgende Fehler:

Exception in thread "main" java.lang.NoClassDefFoundError: Project
Caused by: java.lang.ClassNotFoundException: Project
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: Project. Program will exit.

Ich habe versucht mich über diese Fehlermeldung zu informieren. Anscheinend hat es etwas mit der Main class zu tun.

Könnt ihr mir vielleicht weiter helfen, warum ich den Code nicht zum laufen bekomme????

Wäre echt super!


----------

