Attean/lib/AtteanX/Parser/SPARQLJSON.pm
=head1 NAME
AtteanX::Parser::SPARQLJSON - SPARQL JSON Parser
=head1 VERSION
This document describes AtteanX::Parser::SPARQLJSON version 0.035
=head1 SYNOPSIS
use Attean;
my $parser = Attean->get_parser('SPARQLJSON')->new();
$parser->parse_list_from_io( $fh );
=head1 DESCRIPTION
...
=head1 ATTRIBUTES
=over 4
=item C<< canonical_media_type >>
=item C<< media_types >>
=item C<< file_extensions >>
=back
=head1 METHODS
=over 4
=cut
use v5.14;
use warnings;
package AtteanX::Parser::SPARQLJSON 0.035 {
use Attean;
use Moo;
use JSON;
use Encode qw(decode);
sub canonical_media_type { return "application/sparql-results+json" }
sub media_types {
return [qw(application/sparql-results+json)];
}
sub file_extensions { return [qw(srj)] }
with 'Attean::API::ResultOrTermParser';
with 'Attean::API::Parser';
with 'Attean::API::AtOnceParser';
=item C<< parse_list_from_io( $fh ) >>
=cut
sub parse_list_from_io {
my $self = shift;
my $io = shift;
my $data = do { local($/) = undef; <$io> };
return $self->parse_list_from_bytes($data);
}
=item C<< parse_list_from_bytes( $bytes ) >>
=cut
sub parse_list_from_bytes {
my $self = shift;
my $octets = shift;
my $json = decode('UTF-8', $octets, Encode::FB_CROAK);
my $data = from_json($json, {utf8 => 1});
my $head = $data->{head};
my $vars = $head->{vars};
my $res = $data->{results};
if (defined(my $bool = $data->{boolean})) {
return ($bool) ? Attean::Literal->true : Attean::Literal->false;
} elsif (my $binds = $res->{bindings}) {
my @results;
foreach my $b (@$binds) {
my %data;
foreach my $v (@$vars) {
if (defined(my $value = $b->{ $v })) {
$data{ $v } = $self->decode_node($value);
}
}
push(@results, Attean::Result->new( bindings => \%data ));
}
return @results;
}
}
=item C<< decode_node( \%value ) >>
=cut
sub decode_node {
my $self = shift;
my $value = shift;
my $type = $value->{type};
if ($type eq 'uri') {
my $data = $value->{value};
return $self->new_iri( value => $data );
} elsif ($type eq 'bnode') {
my $data = $value->{value};
return Attean::Blank->new( $data );
} elsif ($type eq 'literal') {
my $data = $value->{value};
if (my $lang = $value->{'xml:lang'}) {
return Attean::Literal->new( value => $data, language => $lang );
} elsif (my $dt = $value->{'datatype'}) {
my $iri = $self->new_iri(value => $dt);
return Attean::Literal->new( value => $data, datatype => $iri );
} else {
return Attean::Literal->new( $data );
}
} elsif ($type eq 'typed-literal') {
my $data = $value->{value};
my $dt = $value->{datatype};
my $iri = $self->new_iri(value => $dt);
return Attean::Literal->new( value => $data, datatype => $iri );
} elsif ($type eq 'triple') {
my $s = $self->decode_node($value->{value}{subject});
my $p = $self->decode_node($value->{value}{predicate});
my $o = $self->decode_node($value->{value}{object});
return Attean::Triple->new( $s, $p, $o );
} else {
die "Unknown node type $type during parsing of SPARQL JSON Results";
}
}
}
1;
__END__
=back
=head1 BUGS
Please report any bugs or feature requests to through the GitHub web interface
at L<https://github.com/kasei/perlrdf/issues>.
=head1 AUTHOR
Gregory Todd Williams C<< <gwilliams@cpan.org> >>
=head1 COPYRIGHT
Copyright (c) 2014--2022 Gregory Todd Williams. This
program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut