Perl: xml nach JSON Umlautproblem

Begonnen von tomKG, 02 Mai 2021, 11:28:03

Vorheriges Thema - Nächstes Thema

tomKG

 8) Moin, 

ich bastel mir für den privaten Gebrauch eine EPG-Übersicht für FTUI3. Mit WebGrab+Plus erstelle ich mir eine xml-Datei die ich anschließend gleich in eine JSON-Datei mit einem kleinem Perl Skript übersetze und nebenbei auch umstrukturiere und entrümpel um sie leichter in Javascript verarbeiten zu können. So weit - So gut.
Leider gelingt es mir nicht Perl zu überreden Umlaute auch als Umlaute in das JSON-File zu schreiben. Ich habe da schon viel probiert ohne Erfolg aber mit viel Frust.
Hier mal mein abgespeckter Beispielcode


#!/usr/bin/perl
use 5.8.0;
use strict;
use warnings;

use open ':encoding(UTF-8)';
use utf8;

binmode STDOUT, ":utf8";

use XML::Simple;
use Encode qw( encode_utf8 );
use JSON qw( encode_json decode_json);
use Data::Dumper;
#$Data::Dumper::Useperl = 1;

use LWP::UserAgent;
use Cwd qw(getcwd);
use Time::Local;

my $inputDir = '/data/smbfritz/epg/perl';
my $outputDir = '/data/smbfritz/epg/perl';
#xml-File zum Einlesen
#<?xml version="1.0" encoding="UTF-8"?>
#<datas>
#  <family id="01">Ää</family>
#  <family id="02">Öö</family>
#  <family id="03">Üü</family>
#  <person family="01">ß</person>
#  <person family="02"></person>
#</datas>

my $inputfile = 'xml.xml';
my $outputfile = 'json.json';

###############################################################################################################

chdir $inputDir or die "path for input \"$inputDir\" not found";

open my $fh, '<', $inputfile or die "Can't open file $!";
my $file_content = do { local $/; <$fh> };
print "file read\n";

my $ref = XMLin($file_content, ForceArray => 1);

utf8::encode(\$ref);

my %epg = %{$ref};

my $json = encode_json (\%epg);
$json = encode_utf8($json);

print "file encoded\n";
chdir $outputDir or die "path for output \"$outputDir\" not found";
open(FH, ">$outputfile");
print FH $json;
close FH;
print "file written\n";
# Result in JSON-File
#{"family":{"03":{"content":"Üü"},"02":{"content":"Öö"},"01":{"content":"Ää"}},"person":[{"content":"ß","family":"01"},{"family":"02"}]}
exit;


Ich sag schon mal Danke für Eure Hilfe

raspberry 3B + Debmatic CCU3
VCONTROL300
HMCCU5
HmIP-eTRV-C-2, HmIP-eTRV-B, Aqara sensors
HM-Sen-MDIR-WM55, HM-LC-Sw2-FM

KölnSolar

Tach,
helfen kann ich Dir leider nicht. Mir fiel nur use XML::Simple;auf und weil ich mich damit gerade beschäftige ein Modul umzuschreiben wg. dem Hinweis auf CPAN
ZitatSTATUS OF THIS MODULE

The use of this module in new code is strongly discouraged. Other modules are available which provide more straightforward and consistent interfaces. In particular, XML::LibXML is highly recommended and you can refer to Perl XML::LibXML by Example for a tutorial introduction.

XML::Twig is another excellent alternative.

The major problems with this module are the large number of options (some of which have unfortunate defaults) and the arbitrary ways in which these options interact - often producing unexpected results.
nur mein Hinweis.
Grüße Markus
RPi3/2 buster/stretch-SamsungAV_E/N-RFXTRX-IT-RSL-NC5462-Oregon-CUL433-GT-TMBBQ-01e-CUL868-FS20-EMGZ-1W(GPIO)-DS18B20-CO2-USBRS232-USBRS422-Betty_Boop-EchoDot-OBIS(Easymeter-Q3/EMH-KW8)-PCA301(S'duino)-Deebot(mqtt2)-zigbee2mqtt

tomKG

Hallo Markus,

vielen Dank, ich werde das berücksichtigen und umschreiben, auch wenn es mein Problem nicht löst.

Grüße aus Bad Kissingen
raspberry 3B + Debmatic CCU3
VCONTROL300
HMCCU5
HmIP-eTRV-C-2, HmIP-eTRV-B, Aqara sensors
HM-Sen-MDIR-WM55, HM-LC-Sw2-FM

mumpitzstuff

Du könntest auch das DOIF hier verwenden und darauf aufbauend deine Oberfläche gestalten. Falls du unbedingt die Datenfiles selbst generieren möchtest, kannst du das sicherlich ohne Probleme anpassen. Die benötigten Readings kannst du jedenfalls aus dem DOIF ohne Probleme auslesen und weiter verwenden.

https://forum.fhem.de/index.php/topic,112081.0.html

tomKG

Moin mumpitzstuff,
ja das hatte ich mir angeschaut, ich war nur an einer Lösung interessiert die, vielleicht später, mal auch weitgehend ohne FHEM funktioniert. Deswegen wollte ich in den Readings nur Parameter übergeben um auf die Daten zugreifen zu können und mir die eigentlichen Daten an FHEM vorbei ziehen.

Grüße Tom
raspberry 3B + Debmatic CCU3
VCONTROL300
HMCCU5
HmIP-eTRV-C-2, HmIP-eTRV-B, Aqara sensors
HM-Sen-MDIR-WM55, HM-LC-Sw2-FM

Otto123

#5
Moin,

da ich auch etwas mit XML und JSON experimentiert habe (ohne das ich bisher ein Umlaut Problem hatte - aber kann ja noch kommen) hab ich mal folgendes probiert.
Und dabei auch diese Diskussion gefunden -> https://forum.fhem.de/index.php?topic=77176.0
Das hier funktioniert (ist einfach für die FHEM Kommandozeile - das ist für mich im Ergebnis immer das Maß der Dinge ;) ):
{use JSON;;my $s= 'ÄäÖöÜüß';;my $s1=Encode::decode_utf8($s);; encode_json {'Umlaute' => $s1}}
Zum Vergleich: Das erzeugt genau das gleiche Problem wie bei Tom:
{use JSON;;my $s= 'ÄäÖöÜüß';;encode_json {'Umlaute' => $s}}

Edit: Rudis Funktion in der fhem.pl macht es mMn auch gut, aber Du wolltest ja eine Funktion außerhalb von FHEM?
{my $s= 'ÄäÖöÜüß';;toJSON {'Umlaute' => $s}}

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

tomKG

Hey Danke Otto,


das probier ich aus und melde mich zurück.

Gruß Tom
raspberry 3B + Debmatic CCU3
VCONTROL300
HMCCU5
HmIP-eTRV-C-2, HmIP-eTRV-B, Aqara sensors
HM-Sen-MDIR-WM55, HM-LC-Sw2-FM

tomKG

Moin,

ich hab es nun gelöst, hat mich aber viel Nerven gekostet. Bin wohl auch etwas unsystematisch rangegangen.
Zuerst bin ich bei der Gelegenheit gleich auf LibXML umgestiegen. (Danke @KölnSolar)

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($inputfile);
my $epg = XML::LibXML::XPathContext->new( $doc->documentElement()  );
foreach my $test ($epg->findnodes('/tv/programme/title'))
{
print $test->textContent."\n";
}

Danach sahen die Daten schon nach dem Einlesen kaputt aus. Durch das entfernen der Zeile

binmode STDOUT, ":utf8";

und den Ersatz von

use open ':encoding(UTF-8)';

durch

use open ':std', ':encoding(UTF-8)';

bekam ich das in den Griff.
JSON lieferte beim Encoding aber immer noch Mist. Hier half mir die Zeile
$json = encode_utf8($json);
durch
utf8::decode($json);
zu ersetzen.
Jetzt ist alles schick, ich danke euch

Tom
raspberry 3B + Debmatic CCU3
VCONTROL300
HMCCU5
HmIP-eTRV-C-2, HmIP-eTRV-B, Aqara sensors
HM-Sen-MDIR-WM55, HM-LC-Sw2-FM