heinetz: Mal wieder Zeichensätze

Hallo Forum,

ich möchte mit den Daten aus einem HTML-Form eine XML schreiben.
Und zwar mit UTF-8. Die Seite mit dem Form ist nun kiene UTF-8
Seite und lässt sich auch nicht als sollche definieren. Unter
Mozilla läuft das ganze seit dem ich im Form
accept-charset="utf-8" geschrieben habe. Mit dem IE allerdings
nicht ;(

Da meckert beim Auslesen php einen Parser-Error an, weil lauter
ü und ö unmaskiert in der XML stehen.

Wie mache ich aus einem 'ö' in $_POST ein 'ö'. Das mag der
XML-Parser nämlich leiden.

danke für Tipps und

beste gruesse,
heinetz

  1. Moin!

    ich möchte mit den Daten aus einem HTML-Form eine XML schreiben.
    Und zwar mit UTF-8. Die Seite mit dem Form ist nun kiene UTF-8
    Seite und lässt sich auch nicht als sollche definieren.

    Doch, das muss gehen, alles andere führt nur in die Irre und sorgt für Datenverlust-

    Unter
    Mozilla läuft das ganze seit dem ich im Form
    accept-charset="utf-8" geschrieben habe. Mit dem IE allerdings
    nicht ;(

    accept-charset ist ganz großer Mist, weil die Browser sich nicht dran halten. Diese Lösung kannst du direkt wieder vergessen.

    Alles muss UTF-8 sein, nur dann funktioniert es: Die Seite mit dem Formular, die Charset-Definition im HTTP-Header, die Charset-Angabe im <meta>, und dann gerne auch noch accept-charset.

    Wenn irgendwas davon nicht UTF-8 ist, funktioniert es nicht.

    Da meckert beim Auslesen php einen Parser-Error an, weil lauter
    ü und ö unmaskiert in der XML stehen.

    Unmaskiert ist nicht das Problem. Sie sind aber falsch codiert - das ist das Problem.

    Wie mache ich aus einem 'ö' in $_POST ein '&#246;'. Das mag der
    XML-Parser nämlich leiden.

    Du hast kein "ö", sondern du hast ein "ö" als ISO-8859-1, brauchst aber eines in UTF-8. Es führt aber zu keiner Lösung, wenn du das jetzt im IE umcodierst, denn du kannst dich einfach nicht drauf verlassen, dass nicht irgendein Browser noch auf ganz andere Codierungsideen kommt - und du kannst auch nicht mit 100% Sicherheit erkennen, welche Codierung der Browser denn verwendet.

    Beseitige das Problem an der Wurzel: Liefere die Formularseite UTF-8-codiert aus!

    - Sven Rautenberg

    1. Moin!

      Beseitige das Problem an der Wurzel: Liefere die Formularseite UTF-8-codiert aus!

      Details: Does accept-charset help in HTML forms?

      Short answer: No.

      Die dort aufgeführte Tabelle sollte abschreckend genug sein!

      - Sven Rautenberg

      1. Moin!,

        ich möchte Dir ja beipflichten, aber das Problem an der
        Wurzel zu packen und alles auf utf-8 umzustellen ist
        leider zu diesem Zeitpunkt definitiv nicht drin. Es muss
        doch möglich sein, das ganze php-seitig umzukodieren!

        gruesse,
        heinetz

        1. Moin!

          ich möchte Dir ja beipflichten, aber das Problem an der
          Wurzel zu packen und alles auf utf-8 umzustellen ist
          leider zu diesem Zeitpunkt definitiv nicht drin. Es muss
          doch möglich sein, das ganze php-seitig umzukodieren!

          Wenn du das Encoding der Seite nicht umstellen kannst, dann bist du gezwungen, das Encoding des Formulars ebenfalls unverändert zu belassen.

          Das wiederum bedeutet, dass du Zeichen, die sich in dem derzeitigen Encoding nicht darstellen lassen, in jedem Fall zerstört werden.

          Den unzerstörten Rest kannst du dann in PHP vom Seitenencoding in UTF-8 umcodieren und in XML speichern. Alternativ könntest du das XML auch direkt im Encoding der Seite lassen, denn vermutlich ist es bei dem Projekt insgesamt schlauer, auf Encoding-Monokultur zu setzen. XML benötigt UTF-8 ja nicht zwingend - und die Zeichen, die im derzeitigen Seiten-Encoding nicht darstellbar sind, sind ja sowieso zerstört.

          - Sven Rautenberg

          1. Moin!

            das alles ist ziemlich komplex:

            Ich habe auf dem Frontend der Site einen Flash-Videoplayer
            eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
            in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
            '&#252;' maskiert.

            Für das Backend habe ich eine Pflegemöglichkeit dieser
            Untertitle gebaut:

            Aus dem XML wird zunächst ein SimpleXML-Object gebildet
            und mit den Werten daraus wird dann ein JS-Array in den
            Quellcode geschrieben. Dort steht dann schon 'ü' statt
            '&#252;'. Aus diesem JS-Array wird dann onload per JS
            ein Form mit input-Feldern und den Werten aus dem JS-Array
            geschrieben.

            Wenn dann das Form abgeschickt wird, wird ein neues XML mit
            den Werten aus diesem Form geschrieben.

            Wenn ich dann das geschriebene XML erneut auf dem beschriebenen
            Web einlese, sind die Umlaute im A****.

            Jetzt frage ich mich, an welcher Stelle gehen Sie kaputt
            gehen.

            gruesse,
            heinetz

            1. Moin!

              das alles ist ziemlich komplex:

              War zu befürchten. Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt. Gegen kaputte Komponenten, die hergestellt wurden von Menschen, die das Prinzip nicht verstanden haben, hilft das allerdings nur bedingt.

              Ich habe auf dem Frontend der Site einen Flash-Videoplayer
              eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
              in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
              '&#252;' maskiert.

              Das ist ja aber nur Lesezugriff auf die Information.

              Die Maskierung hat nichts mit UTF-8 zu tun. Die angegebene Zahl ist zwar der Unicode-Codepoint (in dezimaler Schreibweise), aber die eigentlich interessante Frage ist, ob diese Schreibweise wirklich zwingend ist, oder ob ein entsprechend markiertes XML-File ohne diese numerische Zeichenreferenz vom XML-Parser in Flash auch verstanden wird. Dazu muss das XML allerdings korrekt angeben, welches Encoding verwendet wird.

              Für das Backend habe ich eine Pflegemöglichkeit dieser
              Untertitle gebaut:

              Aus dem XML wird zunächst ein SimpleXML-Object gebildet
              und mit den Werten daraus wird dann ein JS-Array in den
              Quellcode geschrieben. Dort steht dann schon 'ü' statt
              '&#252;'.

              Das ist logisch. Die Schreibweise als numerische Zeichenreferenz wird vom XML-Parser aufgelöst in eine interne Speicherdarstellung des damit gemeinten Zeichens. Welche Form der Speicherung dabei verwendet wird, ist in erster Näherung erstmal irrelevant, solange die Info "intern" bleibt. Interessant wird es aber genau dann, wenn dieser interne Text über ein Interface des XML-Parsers nach außen weitergegeben wird.

              In dem Moment, wo du den String also aus SimpleXML abgreifst, ist relevant, welches Encoding vorliegt. Außerdem ist relevant, wie dieses Encoding dann in das Javascript-Array getan wird, und auf welche Weise das JS-Array ausgeliefert wird.

              Aus diesem JS-Array wird dann onload per JS
              ein Form mit input-Feldern und den Werten aus dem JS-Array
              geschrieben.

              Im Browser und in Javascript ist alles Unicode, egal welches Encoding verwendet wurde, denn der Browser wandelt basierend auf der Encoding-Angabe alle erhaltenen Zeichen sowie auch alle Entities (&auml;) und numerischen Zeichenreferenzen (&#252;) in eine interne Speicherdarstellung für Unicode-Zeichen.

              Wenn dann das Form abgeschickt wird, wird ein neues XML mit
              den Werten aus diesem Form geschrieben.

              Zu diesem Zeitpunkt wandelt der Browser die eingegebenen Zeichen in das Encoding der Seite (wenn Zeichen eingegeben wurden, die nicht im Encoding darstellbar sind, gehen sie dabei auf unterschiedliche Weise, je nach Browser, kaputt) und steckt sie in den POST- (oder auch GET-)Request.

              Wenn ich dann das geschriebene XML erneut auf dem beschriebenen
              Web einlese, sind die Umlaute im A****.

              Beim Schreiben des XML muss natürlich das Encoding wieder beachtet werden.

              Jetzt frage ich mich, an welcher Stelle gehen Sie kaputt
              gehen.

              Du hast an jeder Stelle, wo das Schriftzeichen den Zustand wechselst, ein potentielles Verlustrisiko.

              - Sven Rautenberg

              1. Moin!

                »» das alles ist ziemlich komplex:

                War zu befürchten. Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt. Gegen kaputte Komponenten, die hergestellt wurden von Menschen, die das Prinzip nicht verstanden haben, hilft das allerdings nur bedingt.

                »» Ich habe auf dem Frontend der Site einen Flash-Videoplayer
                »» eingebaut. Dieser Videoplayer includiert ein TimedText-XML,
                »» in dem die Untertitel stehen. Darin ist z.B. ein 'ü' als
                »» '&#252;' maskiert.

                Das ist ja aber nur Lesezugriff auf die Information.

                Die Maskierung hat nichts mit UTF-8 zu tun. Die angegebene Zahl ist zwar der Unicode-Codepoint (in dezimaler Schreibweise), aber die eigentlich interessante Frage ist, ob diese Schreibweise wirklich zwingend ist, oder ob ein entsprechend markiertes XML-File ohne diese numerische Zeichenreferenz vom XML-Parser in Flash auch verstanden wird. Dazu muss das XML allerdings korrekt angeben, welches Encoding verwendet wird.

                OK, ich versuche neu anzufangen, die Maskierungen im xml
                entfernt, "<?xml version="1.0" encoding="UTF-8"?>" in der
                ersten Zeile eingefügt und es als utf-8 kodiert abgespeichert.

                Soweit sogut, wenn die xml nicht etwa aus dem cache geholt
                wird, stellt der flashplayer im Frontend (Darin ist UTF-8
                als Zeichensatz angegeben) alle Zeichen richtig dar. OK

                »» Für das Backend habe ich eine Pflegemöglichkeit dieser
                »» Untertitle gebaut:
                »»
                »» Aus dem XML wird zunächst ein SimpleXML-Object gebildet
                »» und mit den Werten daraus wird dann ein JS-Array in den
                »» Quellcode geschrieben. Dort steht dann schon 'ü' statt
                »» '&#252;'.

                Das ist logisch. Die Schreibweise als numerische Zeichenreferenz wird vom XML-Parser aufgelöst in eine interne Speicherdarstellung des damit gemeinten Zeichens. Welche Form der Speicherung dabei verwendet wird, ist in erster Näherung erstmal irrelevant, solange die Info "intern" bleibt. Interessant wird es aber genau dann, wenn dieser interne Text über ein Interface des XML-Parsers nach außen weitergegeben wird.

                Im Backend, wo der Videoplayer auch angezeigt wird, werden
                die Sonderzeichen im XML von Flash auch richtig dargestellt.
                Die selben Daten durch PHP:simpleXML geparsed und auf der
                (nicht UTF-8) Seite in das JS-Array geschrieben und dann
                in Input-Felder geschrieben, werden in diesen mit kaputten
                Sonderzeichen ausgegeben. Richtig stellen kann ich das,
                indem ich vor der Ausgabe PHP:utf8_decode darauf anwende.

                Das dürfte in dem Kontext richtig sein, oder ?

                Und danach wird es interessant:

                Ich rufe durch Abschicken des (POST) Forms ein PHP-Script
                auf, dass eine neue Datei (UTF-8-encodiert) anlegen und
                die Daten aus POST UTF-8-encodiert dort hineinschreiben
                soll.

                Das POST-Array vor dem Schreiben mit utf8_encode umzuwandeln
                hat geholfen. Das funktioniert also scheinbar.

                Jetzt gibt es aber noch einen neuen Fallstrick:

                Ich lese das XML im Backend nicht direkt ein, sondert kopiere
                es vorher als temp.xml und lese dann das ein. Folgender
                Hintergrund:

                Beim Abschicken des Formulars wird ein PHP-Skript aufgerufen,
                dass das Original.xml mit den Werten aus den Formularfeldern
                überschreibt. Zusätzlich habe ich eine Funktionalität gebaut,
                die diese Daten nicht durch Abschicken des Formulars, sondern
                über einen Ajax.Request an das selbe Skript schickt, dass dann
                aber nicht das Original.xml, sondern dass temp.xml schreibt.
                So lassen sich die Eingaben testen.

                Der einzige Unterschied, den ich mir zwischen dem Abschicken des
                Formulars und dem Ajax.Request vorstellen kann, ist, dass der
                Absender ein Andrer ist.

                tausend dank und

                gruesse,
                heinetz

                1. Moin!

                  »» Deshalb: Encoding-Monokultur, nicht wild wechseln oder umcodieren. Dann geht am wenigsten kaputt.

                  Das würde ich noch einmal unterstreichen. Wobei deine Konstruktion etwas wild ist wegen des AJAX.

                  OK, ich versuche neu anzufangen, die Maskierungen im xml
                  entfernt, "<?xml version="1.0" encoding="UTF-8"?>" in der
                  ersten Zeile eingefügt und es als utf-8 kodiert abgespeichert.

                  Das ist ok.

                  Soweit sogut, wenn die xml nicht etwa aus dem cache geholt
                  wird, stellt der flashplayer im Frontend (Darin ist UTF-8
                  als Zeichensatz angegeben) alle Zeichen richtig dar. OK

                  Und hat Erfolg.

                  Im Backend, wo der Videoplayer auch angezeigt wird, werden
                  die Sonderzeichen im XML von Flash auch richtig dargestellt.
                  Die selben Daten durch PHP:simpleXML geparsed und auf der
                  (nicht UTF-8) Seite in das JS-Array geschrieben und dann
                  in Input-Felder geschrieben, werden in diesen mit kaputten
                  Sonderzeichen ausgegeben. Richtig stellen kann ich das,
                  indem ich vor der Ausgabe PHP:utf8_decode darauf anwende.

                  Das dürfte in dem Kontext richtig sein, oder ?

                  So ist es.

                  Und danach wird es interessant:

                  Ich rufe durch Abschicken des (POST) Forms ein PHP-Script
                  auf, dass eine neue Datei (UTF-8-encodiert) anlegen und
                  die Daten aus POST UTF-8-encodiert dort hineinschreiben
                  soll.

                  Die Daten, die aus dem Formular kommen, sind ISO-8859-1...

                  Das POST-Array vor dem Schreiben mit utf8_encode umzuwandeln
                  hat geholfen. Das funktioniert also scheinbar.

                  ...weswegen das zwingend notwendig ist, sofern das XML in UTF-8 sein soll.

                  Jetzt gibt es aber noch einen neuen Fallstrick:

                  Ich lese das XML im Backend nicht direkt ein, sondert kopiere
                  es vorher als temp.xml und lese dann das ein. Folgender
                  Hintergrund:

                  Beim Abschicken des Formulars wird ein PHP-Skript aufgerufen,
                  dass das Original.xml mit den Werten aus den Formularfeldern
                  überschreibt. Zusätzlich habe ich eine Funktionalität gebaut,
                  die diese Daten nicht durch Abschicken des Formulars, sondern
                  über einen Ajax.Request an das selbe Skript schickt, dass dann
                  aber nicht das Original.xml, sondern dass temp.xml schreibt.
                  So lassen sich die Eingaben testen.

                  Der einzige Unterschied, den ich mir zwischen dem Abschicken des
                  Formulars und dem Ajax.Request vorstellen kann, ist, dass der
                  Absender ein Andrer ist.

                  Alles, was in AJAX läuft, ist zwingend UTF-8-codiert. Das gilt sowohl für Requests, als auch für Responses. Man kann versuchen, das Encoding zu beeinflussen, wird dabei aber derartig eklige Krücken sowie böse Browserbugs entdecken, dass es kein Spaß wird, gegen UTF-8 anzuarbeiten.

                  Deshalb ist es vom Prinzip her doof, dass du einerseite ein ISO-8859-1-codiertes HTML-Formular verarbeitest, andererseits einen UTF-8-codierten AJAX-Request. Das erfordert eine Fallunterscheidung im Code, und führt zu der etwas unschönen Eigenschaft, dass der AJAX-Request via UTF-8 Zeichen senden kann, die im UTF-8-XML auch unterzubringen und vom Flash auslesbar sind, welche aber beim ISO-Formular nicht darstellbar sind und deshalb verloren gehen. Um zumindest den ISO-Darstellungseffekt auch bei AJAX zu haben, musst du den empfangenen String also einmal von UTF-8 nach ISO umcodieren, und dann wieder nach UTF-8 zurückwandeln.

                  PS: Das Eurozeichen gibt's übrigens in ISO-8859-1 nicht - nur für den Fall, dass du es vermisst.

                  - Sven Rautenberg

                  1. echo $begrüßung;

                    PS: Das Eurozeichen gibt's übrigens in ISO-8859-1 nicht - nur für den Fall, dass du es vermisst.

                    Allerdings ist es in Windows-1252 enthalten, was vom Inhalt her betrachtet eine Erweiterung von ISO-8859-1 ist. Meist werden auch die Windows-1252-spezifischen Zeichen, wenn sie in mit ISO-8859-1 deklarierten Dokumenten auftauchen, "richtig" dargestellt. Allerdings sind einige Konvertierungsroutinen deutlich strenger als die Browser und setzen die Windows-1252-spezifischen Zeichen nicht in ihre UTF-8-Pendants um. Man müsste dann im Falle von PHP statt zu utf8_en/decode() zur iconv- oder recode-Extension greifen.

                    echo "$verabschiedung $name";

                  2. Moin,

                    schön, ich habe das Gefühl, den ganzen Zeichensalat sauber (in meinem
                    Kontext) hin- und hercodiert und damit aufgeräumt zu haben. Es ist mir
                    vollkommen klar, dass ich durch konsequnte Einhaltung eines Zeichensatzes
                    viel weniger Arbeit hätte und das ganze erst dann wirklich sauber ist!

                    Du hast mir sehr geholfen. Danke !

                    Alles, was in AJAX läuft, ist zwingend UTF-8-codiert.

                    ... was das Phänomen erklärt:

                    1. die von meinem iso-Form abgeschickten POST-Daten werden
                      vor dem Schreiben mit utf8_encode nach UTF 8 umgewandelt
                      und dann korrekt geschrieben.

                    2. die per Ajax abgeschickten Daten sind schon UTF 8 und
                      werden dann genauso behandelt, also nochmal nach UTF 8
                      umgewandelt, was zum Fehler führt.

                    schoenen dank und

                    beste gruesse,
                    heinetz