Tschechische Zeichen in XML-Antwort

  • Themenstarter Themenstarter Guest
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Guest

Gast
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:
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.
 
Warum so kompliziert? Funktioniert das nicht?
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();
Document document = docBuild.parse(input);
input.close();

Ebenius
 
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)
 
Ich glaube, dieser Fehler tritt auf, weil die XML-Antwort aus mehreren Zeilen besteht.
 
Was passiert bei dem?
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"); 
Reader input = new InputStreamReader(connection.getInputStream(), connection.getContentEncoding()); 
Document document = docBuild.parse(input); 
input.close();
 
In diesem Fall bekomme ich schon beim Kompilieren ein Problem, weil ich der Methode "DocumentBuilder.parse" keinen Reader als Parameter übergeben kann.
 
Entschuldige, hab nicht aufgepasst. Ich meinte eigentlich:
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"); 
Reader input = new InputStreamReader(connection.getInputStream(), connection.getContentEncoding()); 
Document document = docBuild.parse(new InputSource(input)); 
input.close();

Ebenius
 
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.
 
Tut da ein eingeschobenes ...
Code:
connection.connect();
... nach Zeile 5 etwas gutes?
 
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.
 
Ich bin wieder im Forum und würde mich über jede Meldung bezüglich meines Problems freuen.
 
Ich schau's mir grad an. Der Content-Type ist in der Antwort gesetzt, aber irgendwas machen wir wohl noch falsch:
Code:
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
 
So funktioniert's, oder?
Code:
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
 
Vielen Dank,

das muss ich mir erst mal in Ruhe ausprobieren und anschauen.
 
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 ?
 
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?
Code:
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
 
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="urn😱asis: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.
 
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
 
Warum kann aber der Firefox-Browser die Antwort mit allen Zeichen darstellen ?
 
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
 
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.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben