Thomas Schenkeli: UTF-8 Turnaround mit XML- und XSL-Files

Hallo,

ich arbeite gerade dann eine Web-Applikation auf UTF-8 umzustellen. Für POST-Requeste funktioniert das Ganze auch schon ganz gut, nur bei GET-Requesten mangelt es noch.

Meine Frage lauten daher:

  1. Genau welche Zeichen sollen bei einem GET-Request abgeschickt werden?
  2. Genau welche Zeichenkette soll in einem XML zur Interpretation per XSL von der Datenbank zurück kommen?

Erklärung des ganzen: Nehmen wir das €-Zeichen, die UTF-8 Codierung hierfür lautet %E2%82%AC

zu 1) Wenn ich nun aus einem InputFeld ein €-Zeichen auslese und per GET-Request verschicken möchte, was soll dann genau in dem GET-Request stehen:
a) €
b) %E2%82%AC
c) %25E2%2582%25AC (Codierung der %-Zeichen)
d) ? (Ganz was anderes woran ich gar nicht denke)

zu 2) Ich bekomme aus der Datenbank in einem XML-File ein UTF-8 Zeichen, wie soll dieses aussehen:
a) <![CDATA[ € ]]>
b) <![CDATA[ %E2%82%AC ]]>
c) <![CDATA[ %25E2%2582%25AC ]]> (Codierung der %-Zeichen)
d) <![CDATA[ ? ]]> (Ein Fragezeichen weil in XML-Files keine UTF-8 Zeichen dargestellt werden können)
e) ? (Ganz was anderes woran ich gar nicht denke)

Was habe ich bisher schon gemacht?

  1. XSL-Files beginnen mit <?xml version="1.0" encoding="UTF-8"?>
  2. XSL-Files enthalten: <xsl:output encoding="UTF-8" [....] />
  3. XSL-Files enthalten: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> als Teil des HTML-Head-Tags

Damit hätte ich gedacht sage ich der Seite sie soll alles in UTF-8 Abschicken und alles empfangene als UTF-8 interpretieren. Im Moment ist es aber leider so, dass ein €-Zeichen als "%E2%82%AC" abgeschickt wird und auf der nächsten Seite werden drei einzene kryptische Zeichen dargestellt, heisst das Tripplet wird einzeln und nicht als Ganzes interpretiert.

Was mach ich falsch?

Danke für eure Hilfe und lg

Thomas

  1. echo $begrüßung;

    1. Genau welche Zeichen sollen bei einem GET-Request abgeschickt werden?

    Daten, zuerst kodiert gemäß der von der Zeite verwendeten Zeichenkodierung, oder der vom Formular gewünschten (Attribut accept-charset). Anschließend sollten sie URL-kodiert werden.

    1. Genau welche Zeichenkette soll in einem XML zur Interpretation per XSL von der Datenbank zurück kommen?

    Daten, kodiert gemäß der Angabe, die du in den entsprechenden Header-Zeilen gemacht hast. Ob sich für einzelne Bereiche andere Kodierungen angeben lassen, ist mir nicht bekannt.

    Erklärung des ganzen: Nehmen wir das €-Zeichen, die UTF-8 Codierung hierfür lautet %E2%82%AC

    Nein, das ist die URL-kodierte Darstellung eines UTF-8-kodierten Euro-Zeichens

    zu 1) Wenn ich nun aus einem InputFeld ein €-Zeichen auslese und per GET-Request verschicken möchte, was soll dann genau in dem GET-Request stehen:

    Wenn die Seite UTF-8-kodiert ist, und der HTTP-Header "Content-Type" utf-8 sagt, ersatzweise die gleichlautende Meta-Element-Angabe, dann

    a) €
    b) %E2%82%AC

    b. ein URL-kodiertes UTF-8-kodiertes Euro-Zeichen.

    c) %25E2%2582%25AC (Codierung der %-Zeichen)
    d) ? (Ganz was anderes woran ich gar nicht denke)

    zu 2) Ich bekomme aus der Datenbank in einem XML-File ein UTF-8 Zeichen, wie soll dieses aussehen:
    a) <![CDATA[ € ]]>

    a. vorausgesetzt, du schaust dir das mit einem Editor an, der das gemäß UTF-8 interpretiert. Wenn er auf ISO-8859-1 eingestellt ist, siehst du dagegen €

    b) <![CDATA[ %E2%82%AC ]]>
    c) <![CDATA[ %25E2%2582%25AC ]]> (Codierung der %-Zeichen)
    d) <![CDATA[ ? ]]> (Ein Fragezeichen weil in XML-Files keine UTF-8 Zeichen dargestellt werden können)
    e) ? (Ganz was anderes woran ich gar nicht denke)

    Was habe ich bisher schon gemacht?

    1. XSL-Files beginnen mit <?xml version="1.0" encoding="UTF-8"?>
    2. XSL-Files enthalten: <xsl:output encoding="UTF-8" [....] />
    3. XSL-Files enthalten: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> als Teil des HTML-Head-Tags

    Damit hätte ich gedacht sage ich der Seite sie soll alles in UTF-8 Abschicken und alles empfangene als UTF-8 interpretieren.

    Damit weist du (außer bei 2.) den Client an, alles als UTF-8 zu interpretieren. Ist die Kodierung tatsächlich eine andere, dann kann der Client die Daten nicht richtig interpretieren.

    Im Moment ist es aber leider so, dass ein €-Zeichen als "%E2%82%AC" abgeschickt wird und auf der nächsten Seite werden drei einzene kryptische Zeichen dargestellt,

    Wenn die so aussehen: € dann sind das die Byte-Werte eines UTF-8-kodierten Euro-Zeichens, aber als ISO-8859-1 interpretiert.

    echo "$verabschiedung $name";

    1. echo $begrüßung;

      ebenso halli

      Erklärung des ganzen: Nehmen wir das €-Zeichen, die UTF-8 Codierung hierfür lautet %E2%82%AC

      Nein, das ist die URL-kodierte Darstellung eines UTF-8-kodierten Euro-Zeichens

      Danke, das wusste ich nicht. was ist dann die UTF-8 Kodierung: "U+20AC", "e2 82 ac" ?

      zu 1) Wenn ich nun aus einem InputFeld ein €-Zeichen auslese und per GET-Request verschicken möchte, was soll dann genau in dem GET-Request stehen:

      Wenn die Seite UTF-8-kodiert ist, und der HTTP-Header "Content-Type" utf-8 sagt, ersatzweise die gleichlautende Meta-Element-Angabe, dann

      b) %E2%82%AC

      b. ein URL-kodiertes UTF-8-kodiertes Euro-Zeichen.

      Schön, das tut es auch im Firefox, im IE schickt er aber gleich € ab, irgendwelche Ideen warum?

      zu 2) Ich bekomme aus der Datenbank in einem XML-File ein UTF-8 Zeichen, wie soll dieses aussehen:
      a) <![CDATA[ € ]]>

      a. vorausgesetzt, du schaust dir das mit einem Editor an, der das gemäß UTF-8 interpretiert. Wenn er auf ISO-8859-1 eingestellt ist, siehst du dagegen €

      Okay, das ist bei mir der Fall, ich sehe €, wobei ich aber Vermute, dass es schon falsch aus der Datenbank daher kommt, das werde ich aber noch verifizieren (Ich glaube dass C3%A2%C2%82%C2%AC daher kommt und dann eben gemäß UTF-8 als € dargestellt wird.

      echo "$verabschiedung $name";

      Danke schon mal
      Thomas

      1. echo $begrüßung;

        was ist dann die UTF-8 Kodierung: "U+20AC", "e2 82 ac" ?

        Die UTF-8-Kodierung eines € ist eine Byte-Folge mit den hexadezimalen Werten e2 82 ac.

        b) %E2%82%AC
        b. ein URL-kodiertes UTF-8-kodiertes Euro-Zeichen.
        Schön, das tut es auch im Firefox, im IE schickt er aber gleich € ab, irgendwelche Ideen warum?

        Mit anderen Worten: Er sendet es, so wie es aussieht UTF-8-kodiert, aber dann nicht nochmal URL-kodiert.

        Okay, das ist bei mir der Fall, ich sehe €, wobei ich aber Vermute, dass es schon falsch aus der Datenbank daher kommt, das werde ich aber noch verifizieren

        Lass dich nicht von dem täuschen, was du augenscheinlich siehst, weil das bereits von Irgendjemandem interpretiert worden und umgewandelt sein kann. Im Zweifelsfall solltest du dir die Byte-Werte direkt ansehen. Unter PHP beispielsweise kann man sich einen String als Hex-Folge ausgeben, wenn man ihn sich so ausgeben lässt: echo chunk_split(bin2hex($string), 2, ' '); Ansonsten helfen Editoren mit Hex-Modus (z.B. UltraEdit unter Windows) oder andere Hex-Betrachter. Man sollte sich auch immer die Originalwerte ansehen, nicht einfach eine Darstellung kopieren und im Hex-Betrachter einfügen. Da haben schon wieder zu viele Programmteile ihre Finger im Spiel gehabt, die irgendwelche Umwandlungen vorgenommen haben können.

        Die Hex-Werte kann man mit einer Code-Tabelle der jeweils gewünschten Kodierung den Zeichen zuordnen, für die sie stehen.

        Schau doch mal in den Quelltext dieses Postings, am besten mit dem Firefox. Dort suchst du dir mal eine Stelle, an der das € erwähnt wurde. Schalte nun die Zeichenkodierung (im Menü Ansicht) von UTF-8 auf ISO-8859-1 um. Dann siehst du €. Das wäre dann die UTF-8-Kodierung eines UTF-8-kodierten €-Zeichens, also doppelt gemoppelt. Hier ist das so gewünscht, damit diese Seite, die UTF-8-kodiert ausgeliefert wird auch € und nicht € anzeigt. Wenn du aber ein € auf deiner UTF-8-kodierten Seite siehst, und der Browser sich auch auf UTF-8 gestellt hat, dann ist das auch bei dir irgendwo doppelt kodiert, ansonsten interpretiert der Browser die Seite als ISO-8859-1. (Ich hoffe, dieser Abschnitt hat nicht mehr verwirrt, als er aufzuklären versuchte.)

        echo "$verabschiedung $name";

        [*] spielt auch eine Rolle. Da kommt das ‚ aus € (e2 82 ac) her, denn ISO-8859-X definiert den Bereich 80 bis 9F nicht.

        1. Lass dich nicht von dem täuschen, was du augenscheinlich siehst, weil das bereits von Irgendjemandem interpretiert worden und umgewandelt sein kann. Im Zweifelsfall solltest du dir die Byte-Werte direkt ansehen. Unter PHP beispielsweise kann man sich einen String als Hex-Folge ausgeben, wenn man ihn sich so ausgeben lässt: echo chunk_split(bin2hex($string), 2, ' '); Ansonsten helfen Editoren mit Hex-Modus (z.B. UltraEdit unter Windows) oder andere Hex-Betrachter. Man sollte sich auch immer die Originalwerte ansehen, nicht einfach eine Darstellung kopieren und im Hex-Betrachter einfügen. Da haben schon wieder zu viele Programmteile ihre Finger im Spiel gehabt, die irgendwelche Umwandlungen vorgenommen haben können.

          Weißt du auch wie das unter javascript geht?

          Schau doch mal in den Quelltext dieses Postings, am besten mit dem Firefox. Dort suchst du dir mal eine Stelle, an der das € erwähnt wurde. Schalte nun die Zeichenkodierung (im Menü Ansicht) von UTF-8 auf ISO-8859-1 um. Dann siehst du €. Das wäre dann die UTF-8-Kodierung eines UTF-8-kodierten €-Zeichens, also doppelt gemoppelt. Hier ist das so gewünscht, damit diese Seite, die UTF-8-kodiert ausgeliefert wird auch € und nicht € anzeigt. Wenn du aber ein € auf deiner UTF-8-kodierten Seite siehst, und der Browser sich auch auf UTF-8 gestellt hat, dann ist das auch bei dir irgendwo doppelt kodiert, ansonsten interpretiert der Browser die Seite als ISO-8859-1. (Ich hoffe, dieser Abschnitt hat nicht mehr verwirrt, als er aufzuklären versuchte.)

          Im Moment hat er noch mehr verwirrt als aufgeklärt, aber ich glaube nach ein wenig Auseinandersetzung mit dem Thema wird sich das ändern ;-)

          echo "$verabschiedung $name";

          lg und ganz ganz liebe Dank

          Thomas

          1. echo $begrüßung;

            [...] echo chunk_split(bin2hex($string), 2, ' '); [...]
            Weißt du auch wie das unter javascript geht?

            Nein. Das wäre mir auch zu unsicher, da hier schon wieder der Browser seine Finger im Spiel hatte, bevor das Javascript zum Zuge kommt. Ich würde das was vom Server kommt speichern und mit einem Hex-Betrachter untersuchen.

            echo "$verabschiedung $name";