# Tschechische Zeichen in XML-Antwort



## Guest (12. Feb 2009)

Hallo,

ich schicke einen Request an Google zur Abfrage des Geocodes.
Als Antwort bekomme ich einen XML-String.
Das klappt auch soweit ganz gut, bis auf die Umwandlung spezieller Zeichen (Zeichen aus tschechischer Sprache) nach UTF8.
Hier ist mein Code:

```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                        DocumentBuilder docBuild = factory.newDocumentBuilder();
			URL website = new URL(sURL);
			URLConnection connection = website.openConnection();
			connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5");
			InputStream input = connection.getInputStream();
			InputStreamReader isrInput = new InputStreamReader(input);
			BufferedReader br = new BufferedReader(isrInput);
			String sResult = "";
                        String sBRTemp = "";
			while (null != (sBRTemp = br.readLine())) sResult += sBRTemp;
			ByteArrayInputStream docBAIS = new ByteArrayInputStream(sResult.getBytes("UTF-8"));
			Document xmlDoc = docBuild.parse(docBAIS);
```
 
Kann mir bitte jemand sagen, was mir noch fehlt, damit auch die tschechischen Zeichen richtig eingelesen werden.


----------



## Ebenius (12. Feb 2009)

Warum so kompliziert? Funktioniert das nicht?
	
	
	
	





```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuild = factory.newDocumentBuilder();
URL website = new URL(sURL);
URLConnection connection = website.openConnection();
connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5");
InputStream input = connection.getInputStream();
Document document = docBuild.parse(input);
input.close();
```

Ebenius


----------



## Guest (12. Feb 2009)

Wenn ich das so einfach mache, kommt folgender Fehler:

[Fatal Error] :-1:-1: Premature end of file.
Exception in thread "main" org.xml.sax.SAXParseException: Premature end of file.
        at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:264)
        at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:292)
        at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:98)
        at Main.Check_Addresses(Main.java:183)
        at Main.main(Main.java:35)


----------



## Guest (12. Feb 2009)

Ich glaube, dieser Fehler tritt auf, weil die XML-Antwort aus mehreren Zeilen besteht.


----------



## Ebenius (12. Feb 2009)

Was passiert bei dem? 
	
	
	
	





```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder docBuild = factory.newDocumentBuilder(); 
URL website = new URL(sURL); 
URLConnection connection = website.openConnection(); 
connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5"); 
Reader input = new InputStreamReader(connection.getInputStream(), connection.getContentEncoding()); 
Document document = docBuild.parse(input); 
input.close();
```


----------



## Guest (12. Feb 2009)

In diesem Fall bekomme ich schon beim Kompilieren ein Problem, weil ich der Methode "DocumentBuilder.parse"  keinen Reader als Parameter übergeben kann.


----------



## Ebenius (12. Feb 2009)

Entschuldige, hab nicht aufgepasst. Ich meinte eigentlich: 
	
	
	
	





```
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder docBuild = factory.newDocumentBuilder(); 
URL website = new URL(sURL); 
URLConnection connection = website.openConnection(); 
connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5"); 
Reader input = new InputStreamReader(connection.getInputStream(), connection.getContentEncoding()); 
Document document = docBuild.parse(new InputSource(input)); 
input.close();
```

Ebenius


----------



## Guest (12. Feb 2009)

Beim Ausführen wird folgende Exception ausgelöst:
Exception in thread "main" java.lang.NullPointerException: charsetName
        at java.io.InputStreamReader.<init>(InputStreamReader.java:82)
        at Main.Check_Addresses(Main.java:179)
        at Main.main(Main.java:36)

Der Aufruf von "connection.getContentEncoding()" gibt "null" zurück. 
Das ist bestimmt die Ursache für obige Exception.


----------



## Ebenius (12. Feb 2009)

Tut da ein eingeschobenes ... 
	
	
	
	





```
connection.connect();
```
 ... nach Zeile 5 etwas gutes?


----------



## Guest (12. Feb 2009)

Tut mir leid, aber die Methode "connection.getContentEncoding()" gibt immer noch "null" zurück.

Ich muss mich jetzt leider verabschieden, bin aber morgen früh ab 8 Uhr wieder im Forum. Ich würde mich freuen, wenn wir morgen an dieser Stelle weiter machen könnten, da ich mich schon seit Tagen mit diesem Problen rumschlage.


----------



## Guest (13. Feb 2009)

Ich bin wieder im Forum und würde mich über jede Meldung bezüglich meines Problems freuen.


----------



## Ebenius (13. Feb 2009)

Auf welche URL greifst Du denn zu? Ich kann's ja von hier aus mal probieren.


----------



## Guest (13. Feb 2009)

Hallo Ebenius,

die URL baue ich mir immer dynamisch zwecks Google-Abfrage zusammen.
ein Beispiel: http://maps.google.com/maps/geo?q=Shaanxi+Chang'an&gl=CN&output=xml&key=_Key_

Mein Key ist an die IP meines Rechners gebunden, der nützt Dir nichts. Könntest Du Dir selber einen anfordern ? 
Siehe:
http://code.google.com/intl/de-DE/apis/maps/documentation/services.html#Geocoding_Direct


----------



## Ebenius (13. Feb 2009)

Ich schau's mir grad an. Der Content-Type ist in der Antwort gesetzt, aber irgendwas machen wir wohl noch falsch: 
	
	
	
	





```
HTTP/1.1 200 OK
Content-Type: text/xml; charset=ISO-8859-1
Set-Cookie: PREF=ID=1dd3219bf9709b41:TM=1234517657:LM=1234517657:S=Ja47Gngzmxp3vIO1; expires=Sun, 13-Feb-2011 09:34:17 GMT; path=/; domain=.google.com
Date: Fri, 13 Feb 2009 09:34:17 GMT
Server: mfe
Cache-Control: private, x-gzip-ok=""
Transfer-Encoding: chunked
Expires: Fri, 13 Feb 2009 09:34:17 GMT
```
Bis gleich!

Ebenius


----------



## Ebenius (13. Feb 2009)

So funktioniert's, oder? 
	
	
	
	





```
public static void main(String[] args) throws Exception {
  final String urlStr = "http://" //
        + "maps.google.com"
        + "/maps/geo" //
        + "?q=Shaanxi+Chang'an&gl=CN&output=xml";
  final URL url = new URL(urlStr);
  final URLConnection connection = url.openConnection();
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder docBuild = factory.newDocumentBuilder();
  connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5");

  final Charset cs = determineCharset(connection);

  InputStream input = new BufferedInputStream(connection.getInputStream());
  final BufferedReader reader =
        new BufferedReader(new InputStreamReader(input, cs));
  Document document = docBuild.parse(new InputSource(reader));
  input.close();
}

/** Determines the charset to use from the given URL connection. */
private static Charset determineCharset(URLConnection connection) {
  final String contentType = connection.getContentType();
  Charset cs = Charset.defaultCharset();
  if (contentType != null) {
    final Pattern p = Pattern.compile(".*;\\s*charset=(.+)");//$NON-NLS-1$
    final Matcher m = p.matcher(contentType);
    if (m.matches()) {
      final String charsetName = m.group(1);
      try {
        cs = Charset.forName(charsetName);
      } catch (IllegalCharsetNameException ex) {
        // TODO: Logging; Using default charset due to illegal charset name
      } catch (UnsupportedCharsetException ex) {
        // TODO: Logging; Using default charset due to unsupported charset
      } catch (IllegalArgumentException ex) {
        assert false : "The charset cannot be null, here"; //$NON-NLS-1$
      }
    }
  }
  return cs;
}
```

Happy Hacking!
Ebenius


----------



## Guest (13. Feb 2009)

Vielen Dank,

das muss ich mir erst mal in Ruhe ausprobieren und anschauen.


----------



## Guest (13. Feb 2009)

Hallo Ebenius,

ich habe Deinen Code ausprobiert und die Codierung der Verbindung wird korrekt ausgelesen. Aber die Sonderzeichen werden immer noch nicht korrekt ausgelesen. 
Muss der Inhalt des Documents irgendwie in UTF8 umgewandelt werden ?


----------



## Ebenius (13. Feb 2009)

Anonymous hat gesagt.:
			
		

> Hallo Ebenius,
> 
> ich habe Deinen Code ausprobiert und die Codierung der Verbindung wird korrekt ausgelesen. Aber die Sonderzeichen werden immer noch nicht korrekt ausgelesen.
> Muss der Inhalt des Documents irgendwie in UTF8 umgewandelt werden ?


Das sollte eigentlich der XML-Parser anhand der Processing Node selber machen... Kannst Du mal diesen Code ausführen und das ausgegebene XML hier posten? Vielleicht ist ja der Inhalt schlicht falsch? 
	
	
	
	





```
public static void main(String[] args) throws Exception { 
  final String urlStr = YOUR_URL;
  final URL url = new URL(urlStr); 
  final URLConnection connection = url.openConnection(); 
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
  DocumentBuilder docBuild = factory.newDocumentBuilder(); 
  connection.setRequestProperty("Accept-Language", "de-de,de;q=0.5"); 

  final Charset cs = determineCharset(connection); 

  InputStream input = new BufferedInputStream(connection.getInputStream()); 
  final BufferedReader reader = 
        new BufferedReader(new InputStreamReader(input, cs)); 
  String line;
  while ((line = reader.readLine()) != null) {
    System.out.println(line);
  }
  input.close(); 
}
```
Danke, Ebenius


----------



## Guest (13. Feb 2009)

Hier die Antwort:
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
  <name>Shaanxi Chang&an</name>
  <Status>
    <code>200</code>
    <request>geocode</request>
  </Status>
  <Placemark id="p1">
    <address>XiAn, Shaanxi, China</address>
    <AddressDetails Accuracy="4" xmlns="urnasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>CN</CountryNameCode><CountryName>China</CountryName><AdministrativeArea><AdministrativeAreaName>Shaanxi</AdministrativeAreaName><Locality><LocalityName>XiAn</LocalityName></Locality></AdministrativeArea></Country></AddressDetails>
    <ExtendedData>
      <LatLonBox north="34.3720707" south="34.1760922" east="109.1041517" west="108.7775767" />
    </ExtendedData>
    <Point><coordinates>108.9442599,34.2648777,0</coordinates></Point>
  </Placemark>
</Response></kml>

Die Abfrage über Firefox gibt mir aber folgende <address>-Zeile:
<address>Xi’An, Shaanxi, China</address>

In die CSV-Datei wird für das Zeichen "´" ein  unleserliches Zeichen abgespeichert.


----------



## Ebenius (13. Feb 2009)

Sorry, aber da macht google was falsch. Das erste Beispiel von mir oben ist richtig (direkt vom Strom lesen). Das Zeichen worüber man stolpert ist ein 0x92, welches weder in UTF-8 (wie in der XML encoding declaration angegeben) noch in Latin-1 (wie im HTTP-Kopf angegeben) existiert. Richtig wäre, die XML encoding declaration (UTF-8) zu beachten und nur falls diese nicht angegeben ist auf die Kodierung aus dem HTTP-Kopf zurück zu fallen.

In Latin-1 ist 0x92 ein nicht definiertes Zeichen.

In UTF-8 ergibt sich eine ungültige Sequenz. Binär ausgedrückt ist 0x92 = 10010010. Gültig ist in UTF-8:
(x steht nachfolgend für wahlweise 0 oder 1)
0xxxxxxx für ASCII 7bit, ein Bytes pro Zeichen
110xxxxx gefolgt von 10xxxxxx für 2 Bytes pro Zeichen
1110xxxx gefolgt von 10xxxxxx 10xxxxxx für 3 Bytes pro Zeichen
11110xxx gefolgt von 10xxxxxx 10xxxxxx 10xxxxxx für 4 Bytes pro Zeichen
 Bytes wie das obige 0x92 mit einer Maske 10xxxxxx sind sogenannte Folge-Bytes die durch ein Start-Byte (11xxxxxx) eingeleitet werden müssen. Das Byte vor dem Problem-Byte ist aber kein Start-Byte, sondern 0x69 (01101001) was einem normalen mit einem Byte kodierten Zeichen 'i' entspricht.

Also wird Dir nichts übrig bleiben, als Dich an google zu wenden und den Fehler zu beschreiben!

Ebenius


----------



## Guest (13. Feb 2009)

Warum kann aber der Firefox-Browser die Antwort mit allen Zeichen darstellen ?


----------



## Ebenius (13. Feb 2009)

Anonymous hat gesagt.:
			
		

> Warum kann aber der Firefox-Browser die Antwort mit allen Zeichen darstellen ?


Bist Du denn sicher, dass das Zeichen im FireFox das richtige Zeichen ist? Oder soll da vielleicht doch was anderes stehen? Vielleicht rät der Firefox ja das Charset Encoding anhand irgendwelcher schlauer Regeln...?

Oder ich habe irgendwas nicht bedacht; glaub ich aber nach so viel probieren und nachlesen eigentlich nicht.

Ebenius


----------



## Guest (13. Feb 2009)

Die Zeichen im Firefox machen schon Sinn.

Ich danke Dir aber recht herzlich für Deine Bemühungen und Deine Geduld und verabschiede mich jetzt ins Wochenende.


----------

