2016-08-09 63 views
1

Wie kann ich JSON abgeleitete Daten auf die gleiche Weise abfragen wie XPath Abfrage XML?Wie Abfragen von JSON-abgeleiteten Daten wie XPath für XML?

Zum Beispiel, wenn ich die folgenden Daten habe, wie bekomme ich die databaseId wo name entspricht Law Society of New Holland?

$VAR1 = [  
       { 
        'name' => 'Provincial Court of Stratton and Smythe', 
        'jurisdiction' => 'ab', 
        'databaseId' => 'pcss' 
       }, 
       { 
        'name' => 'Law Society of New Holland', 
        'jurisdiction' => 'cd', 
        'databaseId' => 'lsnh' 
       }, 
       { 
        'name' => 'General Protection Tribunal', 
        'jurisdiction' => 'de', 
        'databaseId' => 'gpt' 
       } 
      ]; 
+0

perl könnte wirklich mit einer soliden Implementierung von 'jq' tun. – Sobrique

+0

@Sobrique: Es gibt eine leicht dokumentierte C-API für jq, also sollte es möglich sein. Ich werde mir die Zeit nehmen. – Borodin

Antwort

2

Sie könnten versuchen, die grep (http://perldoc.perl.org/functions/grep.html) und Karte (http://perldoc.perl.org/functions/map.html) Funktionen in Perl verwendet. Gefällt Ihnen dieses

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper; 

my @t = ( 
       { 
        'name' => 'Provincial Court of Stratton and Smythe', 
        'jurisdiction' => 'ab', 
        'databaseId' => 'pcss' 
       }, 
       { 
        'name' => 'Law Society of New Holland', 
        'jurisdiction' => 'cd', 
        'databaseId' => 'lsnh' 
       }, 
       { 
        'name' => 'General Protection Tribunal', 
        'jurisdiction' => 'de', 
        'databaseId' => 'gpt' 
       } 
      ); 

#Just to prove the data is as we think it should be 
print "\nPrint Original data:\n"; 
print Data::Dumper::Dumper(@t); 
print "\n"; 

#now filter to the ones that match the name we want 
my @foo = grep($_->{'name'} eq 'Law Society of New Holland' , @t); 
print "\nPrint filtered data:\n"; 
print Data::Dumper::Dumper(@foo); 
print "\n"; 

#now only list the databaseid's using the map function 
my @bar = map { $_->{'databaseId'} } @foo; 

print "\nPrint only ids:\n"; 
print Data::Dumper::Dumper(@bar); 
print "\n"; 

Grundsätzlich verwenden Sie die grep die Daten filtern nach unten, und die Karte, um diese in ein Array von nur IDs zu konvertieren. Sie könnten es sogar zu einem einzigen Liner machen. Ich habe es etwas länger gelassen, damit es einfacher ist, zu folgen.

1

JSON :: Pfad http://search.cpan.org/~tobyink/JSON-Path-0.205/lib/JSON/Path.pm

Dieses Modul implementiert JSONPath, eine XPath-ähnliche Sprache für Suche JSON-ähnliche Strukturen.

JSONPath wird unter http://goessner.net/articles/JsonPath/ beschrieben.

#!/usr/bin/perl 

#Install JSON::Path 
# I used sudo cpan install JSON::Path 
use strict; 
use warnings; 

use JSON::Path; 
use Data::Dumper; 

# NOTE: The stuff between "?(" and ")" is a Perl expression that must return a boolean, used to filter results. 
# As arbitrary Perl may be used, this is clearly quite dangerous unless used in a controlled environment. 
# Thus, it's disabled by default. This enables it. 
$JSON::Path::Safe = 0; 

# You can read in your json however you want to something in this form. 
my $data = [ 
      { 
       'name' => 'Provincial Court of Stratton and Smythe', 
       'jurisdiction' => 'ab', 
       'databaseId' => 'pcss' 
      }, 
      { 
       'name' => 'Law Society of New Holland', 
       'jurisdiction' => 'cd', 
       'databaseId' => 'lsnh' 
      }, 
      { 
       'name' => 'General Protection Tribunal', 
       'jurisdiction' => 'de', 
       'databaseId' => 'gpt', 
       'price' => 1 
      } 
     ]; 

# We escape the ' around the name. 
# Security warning: This evals perl code DO NOT let users input this search string! (At least not without strict validation). 
my $jpath = JSON::Path->new('$[?($_->{name} eq \'Law Society of New Holland\')].databaseId'); 
my @databaseIds = $jpath->values($data); 

print "Your database Ids are:\n"; 
print Dumper(@databaseIds)."\n"; 

Achtung! Berücksichtigen Sie das Risiko dieser bewertenden Perl für den Bedingungsfilter.

Viel besser, ein Grep und eine Karte zu verwenden, wenn Sie nicht sicher sind, dass es keine schlechte Eingabe hat.

+0

Siehe https://rt.cpan.org/Public/Bug/Display.html?id=115745 – CJ7