JSON auf Gültigkeit prüfen

Begonnen von JudgeDredd, 15 Dezember 2025, 09:00:53

Vorheriges Thema - Nächstes Thema

JudgeDredd

Hallo Zusammen,

mit folgendem Code möchte ich gerne prüfen, ob eine Variable einen gültigen JSON Ausdruck enthält:
$result = 'test';
$result = 'true';
$result = 'false';
$result = true;
$result = false;
$result = '{"text_value": 42,"text_string": "irgendwas","liste": ["A", "B", "C"],"objekt": {"x": 123.45,"y": -67.89,"aktiv": true} }';

print eval { $ifJSON = decode_json( $result ); 1; } ? "OK": "NOK";
Lediglich bei $result = 'test' bekomme ich ein NOK. Alle Anderen liefern mir ein OK, was einen gültigen JSON Ausdruck bedeutet.
Meine Erwartung wäre eher, das nur der letzte String einen gültigen JSON enthält.
Kann mir Jemand sagen wie ich zu meinem Wunschergebnis komme oder bin ich da zu naiv und verstehe da irgendeinen Zusammenhang nicht ?
(Natürlich kommentiere ich bei meinen Tests immer die Zuweisungen entsprechned aus 😉)

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

betateilchen

Dein Problem kann ich nicht nachvollziehen.

sub jt {
  use JSON qw(decode_json);

#  my $result = 'test';
#  my $result = 'true';
#  my $result = 'false';
#  my $result = true;
#  my $result = false;
#  my $result = '{"text_value": 42,"text_string": "irgendwas","liste": ["A", "B", "C"],"objekt": {"x": 123.45,"y": -67.89,"aktiv": true} }';

  my $json_out = eval { decode_json($result) };
  if ($@){
    return "decode_json failed, invalid json. error:$@\n";
  }
  return $json_out;
}


'test' liefert:
decode_json failed, invalid json. error:'true' expected, at character offset 0 (before "test") at ./FHEM/99_myUtils.pm line 40.

'true' liefert:
decode_json failed, invalid json. error:JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at ./FHEM/99_myUtils.pm line 40.

'false' liefert:
decode_json failed, invalid json. error:JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at ./FHEM/99_myUtils.pm line 40.

true liefert:
decode_json failed, invalid json. error:JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at ./FHEM/99_myUtils.pm line 40.

false liefert:
decode_json failed, invalid json. error:JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this) at ./FHEM/99_myUtils.pm line 40.

'{"text_value": 42,"text_string": "irgendwas","liste": ["A", "B", "C"],"objekt": {"x": 123.45,"y": -67.89,"aktiv": true} }' liefert:

HASH(0x564f9cf0c5c0)

Works as designed.

Wobei die Fälle 4+5 (true und false ohne Anführungszeichen) prinzipiell schon in der Zuweisung in einen Fehler laufen, wenn "use strict" gesetzt ist.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

JudgeDredd

Danke schonmal für Deinen Einsatz, aber so ganz kommen wir noch nicht zum gleichen Ergebnis.

Bleiben wir mal bei Deinem Code und einem konkreten Beispiel:
my $result = 'false';
my $json_out = eval { decode_json($result) };
if ($@){
  print "decode_json failed, invalid json. error:$@\n";
}
print $json_out;
Gibt mir eine '0' zurück und das gleiche mit $result='true' eine '1'.

Den von Dir gezeigten Fehler:
JSON text must be an object or array (but found number, string, true, false or null, use allow_nonref to allow this)

bekomme ich bei 'true' und 'false' nicht.
Irgendetwas mache ich noch falsch bzw. anders
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Otto123

#3
Meines Wissens ist 0 und 1 als Rückgabe so zu werten:
0 - perl würde abstürzen wenn man damit eine Zuweisung programmiert. Zumindest war das früher so, ob neue Versionen den Absturz abfangen weiß ich nicht.
1 - perl würde nicht abstürzen, aber es ist eben nur insofern "ok" ;)


Nur wenn ein HASH zurück kommt, hat man wirklich ein array mit den json Daten gefüllt.
Du musst also irgendwie auf das array prüfen. Genau das macht betateilchen mit seinem Code, er prüft den Fehler.
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

JudgeDredd

Danke Otto für Deinen Input, aber
Zitat von: Otto123 am 15 Dezember 2025, 12:31:09Genau das macht betateilchen mit seinem Code, er prüft den Fehler.
Ich mach doch die identische IF-Abfrage. Wieso kommt dann bei Betateilchen ein anderes Ergebnis ? 🤔
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Otto123

Du testest das in FHEM? Da hat bei mir print nie so funktioniert, da nehme ich auch immer return.
Du siehst ja offenbar $json_out, betateilchen "sieht" die Ausgabe von $@
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

JudgeDredd

Zitat von: Otto123 am 15 Dezember 2025, 13:31:26Du testest das in FHEM?
Nein, ich gestehe, der Test erfolgt mit einer Datei auf der Shell.
Aber gut, ich kann das Testweise auch mal in die 99_myUtils.pm nehmen. Ob das return aber das Ergenis verändert ?
Die Frage wäre ja auch noch ... wie geht es dann weiter. Ich benötige am Ende ein ja eine verlässliche Aussage, ob der in $result enthaltene Wert ein Valid JSON ist oder eben nicht.
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

JudgeDredd

UPDATE:
Nein, auch aus der 99_myUtils.pm bekomme ich eine 1
sub validJSON {
  use JSON qw(decode_json);
  my $result='true';
  my $json_out = eval { decode_json($result) };
  if ($@){
    return "decode_json failed, invalid json. error:$@\n";
  }
  return $json_out;
}
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

Schau doch mal hier rein: https://forum.fhem.de/index.php?msg=1227235

Deine Zuweisung erfolgt an der falschen Stelle.
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

JudgeDredd

Hi Beta-User,
reingeschaut habe ich nun, aber wohl immer noch nicht die richtige Stelle für die Zuweisung gefunden.
Auch der Code aus dem referenzierten Post:
my $ref; my $data = 'true';
if ( !eval { $ref = decode_json($data) ; 1 } ) {
          #sonstige Fehlerbehandlungsroutinen hierher, dann ;
          return Log3($hash->{NAME}, 1, "JSON decoding error: $@");
}
liefert mir weiterhin tapfer eine 1.
Hast Du noch einen Tip für die richtige Stelle der Zuweisung ?
Was ich auch nicht verstehe und nachstellen kann, ist, warum bei betateilchens Beispiel im Falle von 'true' der decode_json Befehl ein 'failed' retuniert.
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

Gibst du $ref zurück, oder in welchem Zusammenhang steht jetzt der Schnipsel?
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

JudgeDredd

#11
Zitat von: Beta-User am 16 Dezember 2025, 18:06:31in welchem Zusammenhang steht jetzt der Schnipsel?
Den hatte ich aus dem von Dir verlinkten Beitrag.
Zitat von: Beta-User am 16 Dezember 2025, 18:06:31Gibst du $ref zurück
Korrekt. In diesem Beispiel würde ich $ref zurückgeben.

So ganz grün bin ich mit der IF-Bedingung auch nicht.
bei $data='true' wird ja gar nicht in den Ausführungsteil verzweigt.

EDIT:
Für mich sieht es so aus, als wenn 'true' als gültiges JSON interpretiert wird.
Müsste ein gültiges JSON nicht so aussehen: {'true'}
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

Im Fehlerfall gibst du das Ergebnis des log-Befehls zurück...

Vielleicht wäre es klarer, wenn du entweder nur demo-Code mit Rückgabe zur Eingabe via fhem-Kommandozeile schreibst, oder nur logst...
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors

JudgeDredd

Zitat von: Beta-User am 16 Dezember 2025, 18:38:53Im Fehlerfall gibst du das Ergebnis des log-Befehls zurück...
Es liegt bestimmt an meinem fehlenden Verständnis, aber bei 'true' gibt es ja keinen Fehlerfall (ausser bei betateilchen).
$@ hat keinen Inhalt.

Ich glaube ich such mir einen anderen Weg, das Umzusetzen.
Aber habe dennoch Dank für Deine Bemühungen.

Gruß,
JudgeDredd
Router: Eigenbau (pfSense)
FHEM: Proxmox (DELL R720) | Debian 12 (VM)

Beta-User

Dass "true" gültiges Json sein soll, würde mich überraschen.

Meine vorherige Antwort anders formuliert: verwende zum Verstehen des Codes explizite Return-Werte und keine impliziten.
Server: HP-elitedesk@Debian 13, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: ZigBee2mqtt, MiLight@ESP-GW, BT@OpenMQTTGw | ZWave | SIGNALduino | MapleCUN | RHASSPY
svn: u.a Weekday-&RandomTimer, Twilight,  div. attrTemplate-files, MySensors