Felix Riesterer: € in ISO-8859-1er XML?

Liebe Mitleser,

ich möchte in einer XML-Datei irgendwie das Euro-Zeichen abspeichern. Da die Datei in ISO-8829-1 kodiert ist (default von PHP5 und für mich so in Ordnung), stellt sich nun das Problem, wie das zu bewerkstelligen ist.

Mein Ansatz: Eine numerische Entität (€) in die XML-Datei schreiben.

Selstsamerweise wird beim Parsen der XML-Datei die Entität nicht korrekt aufgelöst und ich erhalte kein Euro-Zeichen (getestet mit ord()). Welche anderen Möglichkeiten seht ihr, um mein Euro-Zeichen in ISO-8859-1 abzuspeichern? Mit ist bewusst, dass ISO-8859-15 das könnte, jedoch ist mir nicht klar, wie ich meine XML-Datei auf dem Server in diesem Format speichern kann.

Warum eigentlich nicht UTF-8? Ich arbeite viel unter Windows und in den Experimentierstadien muss jede text/???-Datei (also HTML, XML, PHP etc.) unter Windows bearbeitbar sein und ohne Störungen per FTP übertragbar sein.

Liebe Grüße aus Ellwangen,

Felix Riesterer.

--
ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
  1. Hi,

    ich möchte in einer XML-Datei irgendwie das Euro-Zeichen abspeichern. Da die Datei in ISO-8829-1 kodiert ist (default von PHP5 und für mich so in Ordnung), stellt sich nun das Problem, wie das zu bewerkstelligen ist.

    Mein Ansatz: Eine numerische Entität (€) in die XML-Datei schreiben.

    Selstsamerweise wird beim Parsen der XML-Datei die Entität nicht korrekt aufgelöst

    Und wer parst, und wie?

    Warum eigentlich nicht UTF-8? Ich arbeite viel unter Windows und in den Experimentierstadien muss jede text/???-Datei (also HTML, XML, PHP etc.) unter Windows bearbeitbar sein

    Und wo waere das Problem, wenn man einen halbwegs tauglichen Editor verwendet?
    (Sogar notepad.exe kann in einer halbwegs aktuellen Version doch AFAIK mit UTF-8 umgehen.)

    und ohne Störungen per FTP übertragbar sein.

    Seit wann "stoert" sich FTP an UTF-8 oder umgekehrt?

    MfG ChrisB

    1. Lieber ChrisB,

      Selstsamerweise wird beim Parsen der XML-Datei die Entität nicht korrekt aufgelöst

      Und wer parst, und wie?

      meine XML-Parser-Klasse ähnlich wie hier

      Und wo waere das Problem, wenn man einen halbwegs tauglichen Editor verwendet?

      Das Problem ist kein Problem, da ich notepad++ verwende. Aber wenn nicht ich, sondern ein DAU mein CMS benutzen möchte, der dann mit Windows Notepad herumalbert, dann ist das nicht mehr kompatibel...

      Seit wann "stoert" sich FTP an UTF-8 oder umgekehrt?

      Je nach Client wird da meines Wissens nicht immer binär übertragen, sondern bei Textdateien irgendwie "herumgefummelt". Aber da lerne ich auch gerne dazu, falls das nicht so sein sollte.

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. Hi,

        Seit wann "stoert" sich FTP an UTF-8 oder umgekehrt?

        Je nach Client wird da meines Wissens nicht immer binär übertragen, sondern bei Textdateien irgendwie "herumgefummelt". Aber da lerne ich auch gerne dazu, falls das nicht so sein sollte.

        Es gibt i.a.R. in den FTP-Clients die beiden Modi Binaer und ASCII zur Auswahl, ja.

        Binaer heisst schlicht und einfach, alles wird 1:1 uebertragen;
        Wohingegen bei ASCII eine Konvertierung der zwischen den OS unterschiedlich gehandhabten Zeilenumbrueche vorgenommen wird - das ist aber auch schon alles. Waehrend es echte Binaerdaten wie bspw. Bilder, Audio-/Videodateien natuerlich in den allermeisten Faellen zerstoert, wenn dort an den entsprechenden Bytewerten (die in diesen ja logischerweise keinerlei "Zeilenumbruch"-Bedeutung haben) herumgepfuscht wird, ist das bei Textdateien harmlos - im worst case erhaeltst du eine Textdatei, deren Umbrueche nicht in dem Format vorliegen, welches das OS normalerweise verwendet. Aber auch damit kann heutzutage jeder [halbwegs brauchbare] Texteditor umgehen.

        MfG ChrisB

      2. Hallo,

        meine XML-Parser-Klasse ähnlich wie hier

        Die arbeitet genauso, wie ich es beschrieben habe, du bekommst immer UTF-8 heraus.

        <?xml version="1.0" encoding="us-ascii" ?>  
        <root>&#8364;</root>
        
        $array_der_xml_daten = new XMLParser('test.xml');  
        $str = $array_der_xml_daten->data[0]['content'];  
        var_dump($str);  
        ini_set('mbstring.internal_encoding', 'UTF-8');  
        echo 'mb_strlen: ' . mb_strlen($str) . "\n";
        

        Da ist alles völlig korrekt. Auf meiner UTF-8-Konsole sehe ich ein Euro-Zeichen. Damit das richtig dekodiert werden kann, muss der Browser natürlich wissen, dass es ein UTF-8-kodiertes Zeichen ist.

        Wenn du jetzt ISO-8859-1 verwenden willst, kannst du diese UTF-8-Bytesequenz natürlich nicht einfach so in ein ISO-8859-1-kodiertes HTML-Dokument einbauen. In dem Fall würde ich dir raten, sie wieder durch den HTML-Entity &euro; zu ersetzen.

        $str2 = str_replace("\xE2\x82\xAC", '&euro;', $str);  
        var_dump($str2);
        

        Alternativ: Schon in der XML-Datei HTML speichern, mit CDATA-Bereich oder Entity-Maskierung von <, > und &.

        <root>&amp;#8364;</root>

        Wenn du das dann ins HTML schreibst, ist es wieder &#8364; und es kommt das richtige Zeichen bei heraus.

        Andererseits wäre eine Umstellung auf UTF-8 ratsam, weil XML immer mit UTF-8 einhergeht.

        Mathias

  2. Hallo,

    Da die Datei in ISO-8829-1 kodiert ist (default von PHP5 und für mich so in Ordnung)

    Das hat nichts mit PHP zu tun. Der XML-Parser arbeitet nach XML-Regeln. Default ist da UTF-8.

    Selstsamerweise wird beim Parsen der XML-Datei die Entität nicht korrekt aufgelöst und ich erhalte kein Euro-Zeichen (getestet mit ord()).

    Natürlich nicht. Falls du das DOM-Modul von PHP verwendest: Aus dem DOM bekommst du einen UTF-8-kodierten String, aber ord() arbeitet BYTEweise, nicht ZEICHENweise, also auf einer ganz anderen Ebene.

    <?php  
      
    $doc = new DOMDocument();  
    $doc->loadXML('<root>&#8364;</root>');  
    $str = $doc->documentElement->firstChild->nodeValue;  
    var_dump($str);  
    echo strlen($str) . "\n";  
    ini_set('mbstring.internal_encoding', 'UTF-8');  
    echo mb_strlen($str) . "\n";  
      
    ?>
    

    Das funktioniert doch prächtig, wenn man den String als UTF-8-String behandelt.

    Welche anderen Möglichkeiten seht ihr, um mein Euro-Zeichen in ISO-8859-1 abzuspeichern?

    Du machst das schon völlig richtig. Und höchstwahrscheinlich arbeitet auch der eingesetzte XML-Parser völlig korrekt und löst die numerische Zeichenreferenz korrekt auf. Der Fehler muss woanders liegen (offenbar ein Denkfehler ;)).

    Mit ist bewusst, dass ISO-8859-15 das könnte, jedoch ist mir nicht klar, wie ich meine XML-Datei auf dem Server in diesem Format speichern kann.

    Mit einem Editor öffnen & speichern, der UTF-8 versteht?? (Jeder gute Editor tut das.)

    Warum eigentlich nicht UTF-8? Ich arbeite viel unter Windows und in den Experimentierstadien muss jede text/???-Datei (also HTML, XML, PHP etc.) unter Windows bearbeitbar sein und ohne Störungen per FTP übertragbar sein.

    Äh?? Windows ist ein Betriebssystem. Was hat Windows damit zu tun? Und was FTP??

    Mathias

    1. Mit einem Editor öffnen & speichern, der UTF-8 versteht?? (Jeder gute Editor tut das.)

      btw: notepad ist kein editor, auch wenn microsoft das sagt :D

      1. Moin.

        Mit einem Editor öffnen & speichern, der UTF-8 versteht?? (Jeder gute Editor tut das.)

        btw: notepad ist kein editor, auch wenn microsoft das sagt :D

        Aktuelle notepad-Versionen können UTF-8 problemlos bearbeiten (verstehen aber nur \r\n als Zeilenumbruch)...

        Christoph

        1. @@Christoph:

          Aktuelle notepad-Versionen können UTF-8 problemlos bearbeiten

          Auch ohne BOM speichern?

          Live long and prosper,
          Gunnar

          --
          Flughafen in Tempelhof
          findet jeder Hempel doof.
          1. Moin.

            Aktuelle notepad-Versionen können UTF-8 problemlos bearbeiten

            Auch ohne BOM speichern?

            Hast mich erwischt - ich hatte testweise eine UTF-8-Datei per 'Speichern unter' neu angelegt und konnte keine Probleme feststellen. Wenn man die Datei vor dem Speichern aber editiert, wird die BOM generiert :(

            Christoph

            1. Moin.

              ich hatte testweise eine UTF-8-Datei per 'Speichern unter' neu angelegt und konnte keine Probleme feststellen.

              Was sich inzwischen aber nicht mehr reproduzieren lässt!? Spinn ich, oder mein PC...

              Christoph

              1. Spinn ich, oder mein PC...

                wenn du notepad verwendest (egal ob zum testen oder produktiv) sind geistige schäden wohl nicht ausgeschlossen :p

    2. Lieber molily,

      Da die Datei in ISO-8829-1 kodiert ist (default von PHP5 und für mich so in Ordnung)

      Das hat nichts mit PHP zu tun. Der XML-Parser arbeitet nach XML-Regeln. Default ist da UTF-8.

      meine XML-Datei beginnt so:

      <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>  
      
      

      Falls du das DOM-Modul von PHP verwendest:

      Tue ich nicht. Offensichtlich ist das für Webspace, der tatsächlich noch PHP4 bereitstellt, nicht verfügbar.

      Du machst das schon völlig richtig. Und höchstwahrscheinlich arbeitet auch der eingesetzte XML-Parser völlig korrekt und löst die numerische Zeichenreferenz korrekt auf. Der Fehler muss woanders liegen (offenbar ein Denkfehler ;)).

      Tja, mit ASCII-Code 128 (ja, als "&#128;"!) wird das Euro-Zeichen "korrekt" gespeichert und auch wieder angezeigt. Ich verstehe das nicht wirklich. Meines Wissens ist in ISO-8859-1 das Euro-Zeichen nicht enthalten. Auch nicht als ASCII-Wert 128. Spielt mir meine Windows-Umgebung da einen Streich? Ich muss das bei Gelegenheit unter "echten" Bedingungen testen. Sehr seltsam das Ganze...

      Liebe Grüße aus Ellwangen,

      Felix Riesterer.

      --
      ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
      1. echo $begrüßung;

        Tja, mit ASCII-Code 128 (ja, als "&#128;"!) wird das Euro-Zeichen "korrekt" gespeichert und auch wieder angezeigt. Ich verstehe das nicht wirklich. Meines Wissens ist in ISO-8859-1 das Euro-Zeichen nicht enthalten. Auch nicht als ASCII-Wert 128. Spielt mir meine Windows-Umgebung da einen Streich?

        Im Bereich x80 bis x9f (128..159) liegen unter ISO-8859-1 keine darstellbaren Zeichen. Jedoch definiert Windows-1252 in diesem Bereich einige Zeichen. Der Rest ist zu ISO-8859-1 kompatibel. (Ebenfalls unter dem angegebenen Link zu sehen.) Die meisten Browser gehen bei Angabe von ISO-8859-1 und Codes aus dem erwähnten Bereich davon aus, dass der Anwender das entsprechende Windows-1252-Zeichen meint und stellen es auch so dar, statt sich mit Bugreports von Windows-Usern über fehlende Euro-Zeichen rumzuschlagen. So wie du das mit dem &#128; beobachtet hast, werden sie diese stillschweigende Korrektur wohl auch auf Unicode übertragen, denn da ist dieser Bereich ebenfalls nicht mit darstellbaren Zeichen belegt. Unicode-Block Latin-1 Supplement (Lateinisch-1, Ergänzung) (0080–00FF)

        echo "$verabschiedung $name";

      2. @@Felix Riesterer:

        Tja, mit ASCII-Code 128 (ja, als "&#128;"!) wird das Euro-Zeichen "korrekt" gespeichert und auch wieder angezeigt.

        Nein.

        „Ein wichtiger Punkt ist, dass die Werte von numerischen Zeichenreferenzen (wie &#x20AC; oder &#8364; für das Euro-Zeichen €) als Zeichencode von Unicode-Zeichen interpretiert werden – unabhängig von der Zeichencodierung des Dokuments. Es ist ein häufiger Fehler, wenn Autoren in Windows-1252-codierten Texten das Euro-Zeichen als &#x80; notieren. Zwar liegt das Euro-Zeichen in der Windows-1252-Codepage auf Position 80 (hexadezimal); aber &#x80; sollte ein Steuerzeichen ergeben, denn das Escape wird aufgelöst zu dem Zeichen auf Position 80 (hexadezimal) im Unicode-Repertoire. (Allerdings korrigieren manche Browser diesen Fehler stillschweigend. Siehe diese Testseiten.)“ [QA-ESCAPES]

        Live long and prosper,
        Gunnar

        --
        Flughafen in Tempelhof
        findet jeder Hempel doof.
      3. Hallo,

        Tja, mit ASCII-Code 128 (ja, als "&#128;"!) wird das Euro-Zeichen "korrekt" gespeichert und auch wieder angezeigt.

        Na das kann auch nicht sein.

        Nochmal der Unterschied zwischen Bytes und Zeichen: Zeichen gibt es nur vor der Kodierung und nach der Dekodierung. Dazwischen gibts Bytes bzw. Bytesequenzen. Kodierungen und damit Dekodierungen gibt es viele.

        Numerische Zeichenreferenzen verweisen, wie Gunnar schon zitiert hat, immer auf Zeichen in der riesigen nummerierten Unicode-Zeichenliste (unabhängig von der Kodierung). &#128; verweist auf das Steuerzeichen U+0080.

        Wenn du nun ein XML-Dokument mit dieser Zeichenreferenz parst, bekommst du auch das Zeichen U+0080 heraus. Und zwar in der Regel als UTF-8 kodiert, das ist die Bytesequenz 0xC2 0x80. Wenn du die als ISO-8859-1 dekodierst / den Browser dies tun lässt, kommt aber Unsinn heraus, nämlich Â[Steuerzeichen]. Und dieses Steuerzeichen wird von den Browsern eben, weil sie fehlertolerant sind, als Windows-1252-kodiertes Eurozeichen angenommen. Dann kommt aber immer noch € heraus.

        Mathias