mit Liste in Json umgehen

Begonnen von Holgi0815, 29 April 2016, 07:18:40

Vorheriges Thema - Nächstes Thema

Holgi0815

Hallo,
ich brauche mal Hilfe bitte, wie ich weiterkommen kann:
Ich hole mit HTTPMOD  Daten im Json Format und schreibe diese in bestimmte Readings. Dies habe ich Dank der guten Hilfe jetzt hinbekommen.
Nun habe ich in diesen Daten noch ein Segment in Listform, und habe bisher nicht raus bekommen, wie ich hieraus auch ein Reading bilden kann!
Beispiel:
Rohdaten
{"status":true,"server":{"name":"Toller Name","version":4711,"Liste":[{"name":"Franz","Wert":333},{"name":"Fritz","Wert":88888}]}}
HTTPMOD Dev "'TEST_JSON": https://url.de/json 60
attr TEST_JSON get01Name Name
attr TEST_JSON get01JSON server_name

gibt mir "Toller Name" zurück

Wie komme ich aber an z.B. den Wert 333 von "Franz" aus dem Objekt "Liste" ran.
Könnte Ihr mir einen Schubs geben?!
Danke Holger
PS: "Fritz" + "Franz" sind nicht immer in dieser Reihenfolge, diese ist zufällig, ich könnte also nicht immer den 1, Wert nehmen

frank

ohne json mit regex würde ich folgendes probieren
attr TEST_JSON get01Regex Franz","Wert":(\d+)
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

Dietmar63

#2
Ohne json Modul kannst du folgenden Code einbauen.
Er wandelt mit einigen geschickten Ersetzungen per regulärem Ausdruck aus einem json String einen Perlstring, der mit eval in ein hash verwandelt wird. Dann kannst du bequem auf die Elemente zugreifen(letzte drei Zeilen) - läuft schon seit Wochen in Twilight, könnte man noch bequem in ein Unterprogramm verwandeln.:

if (defined($result)) {
 
    # ersetze in result(json) ": durch "=>
    # dadurch entsteht ein Perausdruck, der direkt geparst werden kann
     
     my $perlAusdruck = $result;
        $perlAusdruck =~ s/("[\w ]+")(\s*)(:)/$1=>/g;
        $perlAusdruck =~ s/null/undef/g;
        $perlAusdruck =~ s/true/1/g;
        $perlAusdruck =~ s/false/0/g;
        $perlAusdruck = '$resHash = ' .$perlAusdruck;       
     
     my $resHash;
     eval $perlAusdruck;
     Log3 $hash, 3, "[$hash->{NAME}] error $@ parsing $result"   if($@);
   
     $cond_code  = $resHash->{query}{results}{channel}{item}{condition}{code};
     $cond_txt   = $resHash->{query}{results}{channel}{item}{condition}{text};
     $temperatur = $resHash->{query}{results}{channel}{item}{condition}{temp};
     
  }


bei dir müsste der Zugriff so aussehen:

my $listeNutzer = $resHash->{server}{Liste};

Die Liste dann zu Fuß abklappern - wie bei einem Array üblich. Eventuell mit dem Dumper dumpen.

Wenn du Pech hast muss an den regulärden Ausdrücken noch geschraubt werden.
Bitte melden wenn es nicht klappt.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Dietmar63

Habe mal schnell ausprobiert ob es funktioniert. Und es klappt.
Habe auch gleich eine kleine Funktion gebaut - kannst du in die 99_utis einbauen und dann aufrufen:


#!/usr/local/bin/perl

use strict;
use Data::Dumper;

my $json =
'{"status":true,"server":{"name":"Toller Name","version":4711,"Liste":[{"name":"Franz","Wert":333},{"name":"Fritz","Wert":88888}]}}'   
    ;   
my  $resHash = jsonAsPerlHash($json);       
print "jsonAsPerl". Dumper $resHash;     

foreach my $hash (@{$resHash->{server}{Liste}}) {
    print "$hash->{name} -> $hash->{name}\n";
}
###################################################
###################################################
###################################################
sub jsonAsPerlHash ($)   {
   my ($json) = @_;
   
   my $perlAusdruck = $json;
      $perlAusdruck =~ s/("[\w-: ]+")(\s*)(:)/$1=>/g;
      $perlAusdruck =~ s/null/undef/g;
      $perlAusdruck =~ s/true/1/g;
      $perlAusdruck =~ s/false/0/g;
      $perlAusdruck = '$resHash = ' .$perlAusdruck;       
     
   my $resHash;
   eval $perlAusdruck;
   print "[json] error $@ parsing $json\n"   if($@);
   return $resHash;
}



jsonAsPerl$VAR1 = {
          'server' => {
                        'name' => 'Toller Name',
                        'Liste' => [
                                     {
                                       'name' => 'Franz',
                                       'Wert' => 333
                                     },
                                     {
                                       'name' => 'Fritz',
                                       'Wert' => 88888
                                     }
                                   ],
                        'version' => 4711
                      },
          'status' => 1
        };
Franz -> Franz
Fritz -> Fritz

Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm

Holgi0815

Danke Dietmar,
ich werde mal mein Glück versuchen das bei mir umzusetzen!
VG Holger

Dietmar63

#5
HTTPMOD wurde so erweitert, dass es mit
attr test extractAllJSON 1
JSON komplett in Readings einliest. Dann musst du dir Dein Attribut heraussuchen - Wahrscheinlich ist das einfacher für dich.
Gruß Dietmar
FB7390, CUL, 2 FHT, FS20
modules: 98_WOL.pm, 98_Heating_Control.pm,   98_WeekdayTimer.pm, 98_RandomTimer.pm, 59_Twilight.pm