Hauptmenü

Umlaute (utf-8) in fhem

Begonnen von Elektrolurch, 20 Februar 2022, 13:02:32

Vorheriges Thema - Nächstes Thema

Elektrolurch

Hallo,

ich habe folgendes Problem: Ich möchte eine XML - Datei einlesen und Teile davon in fhem darstellen.
Im Kopf der Datei steht:

<?xml version="1.0" encoding="UTF-8"?>


Wenn ich die XML - Datei mit Notepad öffne, erscheinen die Umlaute korrekt.
Ich lese diese dann mit einem perl-Skript ein und schreibe ein Teil als hash per Dumper in eine Datei.
Wenn ich diese Datei nun mit Notepad öffne, sind nun dort die Umlaute ersetzt worden:
Die Umlaute und andere Sonderzeichen sind immer in der Form \x[<hexzahl>} kodiert. Beispiel

'title' => "Bares f\x{fc}r Rares - H\x{e4}ndlerst\x{fc}cke",
                             


Wenn ich das nun in fhem darstelle, steht auf dem Screen dann ein "nicht aussprechbares" Zeichen.

Was muss ich da tun, damit die Umlaute erhalten bleiben?

Elektrolurch
configDB und Windows befreite Zone!

betateilchen

Falsches Forum für diese Frage.
Du solltest das besser in Frontends -> FHEMWEB fragen, weil Rudi gerade an der generellen Zeichenkodierungs-Problematik in FHEM rumschraubt.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

herrmannj

#2
das stimmt zwar, aber:

da der TE das file einliest, ist der TE dafür verantwortlich dass die Daten korrekt eingelesen werden. Generell: attr UNICODE setzen. Beim einlesen: wenn die Daten utf8 kodiert sind (hier der fall), als utf8 einlesen (dann wandelt perl selber das in text), oder als binary einlesen und nach dem einlesen von manuell von utf8 nach text umwandeln.

Für weitere Hilfe ist der konkrete code erforderlich. Den hash per Dumper in eine Datei schreiben halte ich für eine Notlösung, da sollte man besser JSON zum serialisieren verwenden.

Elektrolurch

Hallo,

schuldigen gefunden:


use XML::Bare 0.53 qw(forcearray);
...
my $obj = XML::Bare->new(file => $config{TV_filename});
  my $xml = $obj->parse();

Dann sind die eingelesenen Zeilen mit den Umlauten als \x{hexnumber} codiert.
Wenn ich die XML - datei zeilenweise einlese und selbst in einen hash umwandele, bleiben die UTF-8 codierten Umlaute erhalten und lassen sich auch per Dumper ohne Probleme in eine json - Datei schreiben.
siehe auch:
https://forum.fhem.de/index.php/topic,126088.0/topicseen.html

Elektrolurch
configDB und Windows befreite Zone!

herrmannj

#4
hi, cool.

ja, den Beitrag habe ich geschrieben um modulautoren zu unterstützen. Im Nachgang eher unglücklich hat dass ausgelöst das Rudi in gewohnter Manier anfängt rumzufrickeln und zu basteln, das nimmt einen unglücklichen Lauf.

Vom selber einlesen würde ich abraten. Da gibt es eine lib für, die ist sicher deutlich ausgereifter als das was man selber schreibt. vmtl. "Probleme" mit professionellen libs sind das Ergebnis von dem amateurhaften rumgestümper in fhem.pl. Nimm die lib, nicht das Rad neu erfinden.

Du musst Dich allerdings mit utf8 und unicode an des links oben beschätigen (wenn Du das richtig machen möchtest) um die Unterschiede zu verstehen. Meine Empfehlung, betrachte alles in Deinem modul als text (-> unicode, so wie der Rest der Welt das seit den 80ern auch macht), alles in fhem.pl als verseucht. Dazwischen ist die Grenze.

Je nachdem wo die XML herkommt also am Eingang Deines moduls entweder konvertieren:
use Encode qw(encode decode find_encoding);
eval {$uc = decode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};

aktuelle fhem.pl so:
eval {$uc = decode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)} if !($unicodeEncoding);

Falls die XML von der disk kommt kannst Du die auch gleich richtig einlesen
open my $handle, '<:encoding(UTF-8)', $name

Alles was aus Deinem modul Richtung fhem.pl rausgeht:
eval {$uc = encode(find_encoding('UTF-8'), $uc, Encode::FB_CROAK)};
neuere fhem.pl wieder mit if !($unicodeEncoding)

Rausgehen meint alles. In readings schreiben, in attribute schreiben, loggen, ausgabe via statefn etc.

Das mit dem $unicodeEncoding ist natürlich fürn A*** weil das in älteren Versionen nicht da ist. Du kannst daher ersatzweise die entsprechende attrval nehmen und das default auf undef setzen, dann ist es abwärtskompatibel.

Das gilt, btw, auch für Dumper und JSON. Wenn die Werte sowieso schon in einem hash sind und Du strukturiert speichern möchtest, dann nimm lieber "use JSON;" und installiere auch cpanel:json:xs (als backend).

Wenn Du dann selber auf der disc speicherst: entweder die utf8 Ausgabe Optionen von JSON nutzen (siehe CPAN doku) oder dies explizit nicht tun und den perl io layer nutzen (siehe file open...). Da aber nicht beides.

und oben im modul "use utf8" reinschreiben

hope that helps

Nachtrag, ich seh grad oben das Du geschrieben hast,
<?xml version="1.0" encoding="UTF-8"?>
Im idealfall versteht die lib alleine damit was zu tun ist. Dann normal einlesen (als bytestream, nicht konvertieren) dann die lib ihren job machen lassen. Das ist genauso wie es normal funktioniert. Am Ausgang ist dann normaler text. Beim Ausgeben das machen was ich oben geschrieben habe