Umlautdarstellung unterschied in Android 2.3.x vs 4.0.x

  • Tja, ich hätte da gern mal wieder ein Problem.


    Grundlage der Datenhaltung sind XML Dokumente kodiert als UTF-8.
    Diese lese ich ein, packe sie via greenDAO in eigene persistente Objekte und stelle sie dann dar.


    Lustig:


    Android 4.0.3 sagt:

    Zitat

    5 am Tag sorgt für gesunden Spaß
    Öffentliche Pflanzaktion von Rosen
    Gartenwelt und Rosenträume


    Android 2.3.5 sagt:

    Zitat

    5 am Tag sorgt f
    Ö
    Gartenwelt und Rosentr


    Gibt es irgendwelche Unterschiede im Handling von XML bei den unterschiedlichen Versionen, so dass ich unter 2.3 ein anderes Ergebnis bekomme als unter 4.0?


    Der XML Parser basiert komplett auf java.io, java.xml, org.xml.sax und org.w3c.dom, es ist also nichts dabei, dass ich als unsupporteten Drittherstellerkrams ansehen würde...


    Für sachdienliche Hinweise bin ich dankbar. ^^

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Moin,


    ich muss das noch mal ansprechen. ^^


    Das Problem scheint in dem Zusammenspiel der XML und den XMLParser Bibliotheken zu liegen.


    Die Umlaute im XML sind websafe als UTF-8 kodiert, also ü = ü und so weiter.


    Dieselbe Klasse mit dem javax.xml.parsers.DocumentBuilder liefert unter 2.3 allerdings nicht die Umlaute, die es unter 4.0 liefert.
    Stattdessen bricht es einfach ab.


    Wenn ich mir die Werte ausgeben lasse, fehlen die Umlaute bereits beim Abholen aus dem XML.
    Betreffende Zeilen Code:


    Der XML String "Frühling" bringt mir dann bei 4.0 das Ergebnis 'Frühling' und bei 2.3 das Ergebnis 'Fr'.
    Angeblich sei die Methode getNodeValue() bereits seit API 1 eingepflegt, so dass es natürlich schwer ist festzustellen, was sich da in deren Implementierung geändert hat.


    Hat jemand einen Tipp für mich, wie ich dieses Problem behoben bekomme?
    (Da Inhalte aus der XML aus einer Webquelle stammen und die Darstellung der Zeichen unter 4.0 ja keinerlei Probleme verursacht, würde ich ungern das XML auf 'irgend ein anderes Symbol als die UTF-8 Darstellung' umbauen müssen.)

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Danke für den Tipp Kogoro.


    Ich fürchte nur, dass das eben dieser Bug ist. ;)


    Tausche ich im XML das 'Fr&#xFChling' gegen ein 'Frühling', dann passt es wieder.
    Auch werden mir nicht die Uppercase Umlaute abgeschnitten, sondern das Sonderzeichen mitsamt Rest gar nicht erst angezeigt.
    Außer, das Sonderzeichen ist an erster Stelle, dann wird nur der Rest nicht angezeigt.


    Anbei zwei Screenshots mit Testdaten.
    Die XML dazu sieht simpel und wie folgt aus:


  • Hmm aber irgendwie sieht dein XML auch nicht valide aus, wenn deine Datei UTF-8 ist sollten doch die Umlaute auch als solche sichtbar sein.


    Ich glaube der Fehler liegt schon vorher irgendwo im Encoding.
    Woher kommen die Daten ? Kannst du mal eine Probeausgabe zb in PHP machen ?

  • Die Umlaute als solche sind sichtbar, wenn ich sie im Klartext im XML eintipper.
    Aus Kompatibilitätsgründen mit einigen WebViews sind sie Umlaute in der XML halt UTF-8 HTML Encoded.
    Das beschriebene Encoding ist UTF-8, das Dateiencoding ist UTF-8 und Android 4.0 stellt die HTML-Encoded UTF-8 Chars vernünftig dar, nur Android 2.3 nicht.


    Fun fact: drehe ich den Spieß um und nehme statt UTF-8 kodierter HTML-Werte das normale HTML-Encoding (in diesem Fall beispielsweise ü), dann werden die derart formatierten Zeichen unter 2.3 einfach nur ausgelassen:


    Zitat

    Frhling
    Der Sandmann


    Im Übrigen ist das auch gar nicht mein XML.
    Mein XML hat immer entweder eine Inline-DTD oder eine importierte DTD, woher soll der Parser sonst wissen, was er damit alles tun kann?


    Ich werde also bei Zeiten mal mit dem Ersteller der XML verhandeln, ob man die Zeichen nicht einfach in Klartext in das Dokument bekommt.


    Nichts desto trotz wundert mich, dass dieselbe Implementierung bei derselben Datei auf unterschiedlichen OS-Versionen so eine unterschiedliche Darstellung zur Folge hat. Was wird mir noch alles begegnen? 8|

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Ok klingt alles etwas vermurkst von Google wenn die Webviews schon Mist bauen.


    Hast du mal statt dem "normalen" Webview den Chromeclient benutzt.


    mwebview.setWebChromeClient(new WebChromeClient() {
    }


    Hast du das Encoding im Webview auch gesetzt bzw damit rum experimentiert ?
    WebSettings settings = mWebView.getSettings();
    settings.setDefaultTextEncodingName("utf-8");



    bzw. beim laden





    mWebView.loadDataWithBaseURL(null,meinePage,"text/html","utf-8",null);



    Wichtig loaddatawithbaseurl -> weil loaddata alleine Probleme machen soll.
    Eventuell ein Versuch wert.

  • Hab noch ein bisschen weiter am XML gespielt und eine vernünftige DTD eingetragen sowie die UTF-8 als auch die HTML Entities verwendet.
    Die spannenden Ergebnisse hängen an.


    Das XML dazu sieht aus wie folgt:


    Also nicht großartig anders, nur dass ich den ursprünglichen Bodytext in eine Kurzbeschreibung umgebaut habe. Die Titel haben HTML-Entities, die Kurzbeschreibungen haben (wenn überhaupt) die UTF-8 codierten Entities.


    Man beachte beim ersten Bild (2.3) dass da kaum was stimmt und beim zweiten Bild (4.0), dass zwar die Umlaute in den UTF-8 Encodings sowie die XML-eigenen Entities dargestellt werden, die Umlaute in HTML-Entities hingegen nicht.


    An meiner Ursprungsfrage ändert das jedoch nichts:
    warum kann 4.0 die UTF-8 kodierten Zeichen als String ausgeben, während 2.3 an der Stelle abbricht?


    Da mir das Ganze nach einem gewaltigen Systembug in 2.3 und kleiner riecht, es aber noch immer zu weit verbreitet ist als dass man es wegfallen lassen könnte (was ich echt liebend gern täte... +seufz+): welche Stelle ist die Richtige, um ein erstelltes Testprojekt zur Darstellung dieses Bugs abzuliefern?


    [killphil75]
    Nein, den WebChromeClient habe ich nicht ausprobiert.
    Ja, das Encoding steht explizit auf UTF-8.
    Ja, ich nutze loadDataWithBaseURL(), weil ich mit loadData() nur Probleme hatte.


    Danke für den Tipp mit dem WebChromeClient. :)

  • Zitat

    An meiner Ursprungsfrage ändert das jedoch nichts:


    warum kann 4.0 die UTF-8 kodierten Zeichen als String ausgeben, während 2.3 an der Stelle abbricht?

    Kannst du mal etwas Code zeigen, speziell wie du die XML ausliest (es gibt bekannte Probleme hinsichtlich, XMLReader / Inputstream - ebenfalls wegen Encoding)


    Und noch die Königsfrage wie gibst du die Sachen aus bzw wenn im Webview wie formatierst du die Ausgabe ?


    Hast du mal nach dem "Auslesen" deiner XML ins Log geschaut bzw. dir ausgeben lassen was dort so erkannt wird ?



    10min später


    -- Also ich hab mir mal eben dein XML File kopiert und selber ausgelesen.
    Und es kommt wie es kommen muss, XML zickt bei dem ü weil er das nicht kennt.


    Ursache hier: http://en.wikipedia.org/wiki/L…aracter_entity_references


    Wenn ich das einfach mal als ü umschreibe, kann ich alles andere aber super auslesen. (Ich habs nur mal unter 2.3 getestet, weil du sagst da klemmt es).

  • Nun, der Code bezüglich des Auslesens steht ja im zweiten Beitrag.
    Dort habe ich mir einfach im Log child.getNodeValue() ausgeben lassen und festgestellt, dass dort die ü schon fehlten.


    Dass die ü ein genereller Fehler sind, habe ich bereits festgestellt. Es ist ja quasi als Test drin, ob die Parser mit Fehlern gleich umgehen.


    Ich bekomme keinerlei Log-Ausgaben bezüglich des XML-Parsens, die ich nicht selbst abgegeben habe, außer:

    Zitat

    11-30 15:06:50.693: VERBOSE/BaseXMLParser#parse(787): done parsing xml


    Hast du den SAX oder den DOM Parser genutzt?
    Bei mir wird wie gesagt einfach alles inklusive des ersten Umlauts abgeschnitten...


    Der gesamte Parser sieht so aus:

    Je mehr Käse, desto mehr Löcher.
    Je mehr Löcher, desto weniger Käse.
    Daraus folgt: je mehr Käse, desto weniger Käse.


    »Dies ist ein Forum. Schreibt Eure Fragen in das Forum, nicht per PN!«

  • Ich bin ein ganz schlimmer XMLPullParser Nutzer. Ist irgendwie am einfachsten.
    Ich muss gleich weg aber ich schau mir heute Abend noch mal deinen Code an. Wenn die Childerkennung die Unicodezeichen wegschmeisst dann kann es ja nur dort irgendwo klemmen.

  • Der Domparser ist ein Drecksparser,
    jetzt habe ich zwei Stunden etwas rumgetestet und Sachen ausprobiert.


    Vorher die Entitys bereinigt, aber die Unicodezeichen machten immer noch Probleme.
    Und nun hab ich eine Lösung die ganz einfach ist.



    Java
    public String xmlFromStream(InputStream stream) throws UnsupportedEncodingException
    		{
    			BufferedReader r = new BufferedReader(new InputStreamReader(stream,"UTF-8"));


    Java
    public final String getElementValue( Node elem ) {
    			Node child;
    			if( elem != null){
    				
    				elem.normalize();
    				
    		    	if (elem.hasChildNodes()){
    		        	for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
    		            	if( child.getNodeType() == Node.TEXT_NODE  ){





    elem.normalize();


    Scheint die Strings glattzubügeln damit der Parser drüber kommt. Dann zeigt er hier alles sauber an

  • Büdde, hab ja auch wieder was dabei gelernt.


    Ich vermute mal das die Google-Jungs unter Android 4+ (oder vielleicht auch schon 3+) den DomParser soweit geändert haben, das Sie die Textelemente vorher normalizen. Das würde das Verhalten erklären 4.0 vs. 2.3 - um das zu Prüfen könnte man zwar in den SDK Source schauen aber den müsste ich erst downloaden und durchforsten... ach neee ... heute nicht :)


    Hauptsache es funktioniert nun.


    DIe UTF-8 Nummer beim Inputstream ist nur so ein Sicherheitsding, irgendwo stand geschrieben das bei manchen Androidgeräten der Stream als ISO angenommen wird, deswegen lieber den expliziten Konstruktor mit UTF

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!