1# RDF::Trine::Serializer::TSV 2# ----------------------------------------------------------------------------- 3 4=head1 NAME 5 6RDF::Trine::Serializer::TSV - TSV Serializer 7 8=head1 VERSION 9 10This document describes RDF::Trine::Store version 1.019 11 12=head1 SYNOPSIS 13 14 use RDF::Trine::Serializer::TSV; 15 my $serializer = RDF::Trine::Serializer::TSV->new(); 16 17=head1 DESCRIPTION 18 19The RDF::Trine::Serializer::TSV class provides an API for serializing RDF 20graphs to the TSV syntax. 21 22=head1 METHODS 23 24Beyond the methods documented below, this class inherits methods from the 25L<RDF::Trine::Serializer> class. 26 27=over 4 28 29=cut 30 31package RDF::Trine::Serializer::TSV; 32 33use strict; 34use warnings; 35use base qw(RDF::Trine::Serializer); 36 37use URI; 38use Carp; 39use Data::Dumper; 40use Scalar::Util qw(blessed); 41 42use RDF::Trine::Node; 43use RDF::Trine::Statement; 44use RDF::Trine::Error qw(:try); 45 46###################################################################### 47 48our ($VERSION); 49BEGIN { 50 $VERSION = '1.019'; 51 $RDF::Trine::Serializer::serializer_names{ 'tsv' } = __PACKAGE__; 52 $RDF::Trine::Serializer::format_uris{ 'http://www.w3.org/ns/formats/TSV' } = __PACKAGE__; 53 foreach my $type (qw(text/tsv)) { 54 $RDF::Trine::Serializer::media_types{ $type } = __PACKAGE__; 55 } 56} 57 58###################################################################### 59 60=item C<< new >> 61 62Returns a new TSV serializer object. 63 64=cut 65 66sub new { 67 my $class = shift; 68 my %args = @_; 69 my $self = bless( {}, $class); 70 return $self; 71} 72 73=item C<< serialize_model_to_file ( $fh, $model ) >> 74 75Serializes the C<$model> to TSV, printing the results to the supplied 76filehandle C<<$fh>>. 77 78=cut 79 80sub serialize_model_to_file { 81 my $self = shift; 82 my $file = shift; 83 my $model = shift; 84 my $st = RDF::Trine::Statement->new( map { RDF::Trine::Node::Variable->new($_) } qw(s p o) ); 85 my $pat = RDF::Trine::Pattern->new( $st ); 86 my $stream = $model->get_pattern( $pat, undef, orderby => [ qw(s ASC p ASC o ASC) ] ); 87 my $iter = $stream->as_statements( qw(s p o) ); 88 print {$file} join("\t", qw(s p o)) . "\n"; 89 while (my $st = $iter->next) { 90 print {$file} $self->statement_as_string( $st ); 91 } 92} 93 94=item C<< serialize_model_to_string ( $model ) >> 95 96Serializes the C<$model> to TSV, returning the result as a string. 97 98=cut 99 100sub serialize_model_to_string { 101 my $self = shift; 102 my $model = shift; 103 my $st = RDF::Trine::Statement->new( map { RDF::Trine::Node::Variable->new($_) } qw(s p o) ); 104 my $pat = RDF::Trine::Pattern->new( $st ); 105 my $stream = $model->get_pattern( $pat, undef, orderby => [ qw(s ASC p ASC o ASC) ] ); 106 my $iter = $stream->as_statements( qw(s p o) ); 107 108 my $string = join("\t", qw(s p o)) . "\n"; 109 while (my $st = $iter->next) { 110 my @nodes = $st->nodes; 111 $string .= $self->statement_as_string( $st ); 112 } 113 return $string; 114} 115 116=item C<< serialize_iterator_to_file ( $file, $iter ) >> 117 118Serializes the iterator to TSV, printing the results to the supplied 119filehandle C<<$fh>>. 120 121=cut 122 123sub serialize_iterator_to_file { 124 my $self = shift; 125 my $file = shift; 126 my $iter = shift; 127 my $e = $iter->peek; 128 129 if (defined($e) and blessed($e) and $e->isa('RDF::Trine::Statement')) { 130 print {$file} join("\t", qw(?s ?p ?o)) . "\n"; 131 while (my $st = $iter->next) { 132 print {$file} $self->statement_as_string( $st ); 133 } 134 } elsif (defined($e) and blessed($e) and $e->isa('RDF::Trine::VariableBindings')) { 135 my @names = $iter->binding_names; 136 print {$file} join("\t", map { "?$_" } @names) . "\n"; 137 while (my $r = $iter->next) { 138 print {$file} $self->result_as_string( $r, \@names ); 139 } 140 } 141} 142 143=item C<< serialize_iterator_to_string ( $iter ) >> 144 145Serializes the iterator to TSV, returning the result as a string. 146 147=cut 148 149sub serialize_iterator_to_string { 150 my $self = shift; 151 my $iter = shift; 152 153 # TODO: must print the header line corresponding to the bindings in the entire iterator... 154 my $string = ''; 155 my $e = $iter->peek; 156 if (defined($e) and blessed($e) and $e->isa('RDF::Trine::Statement')) { 157 $string .= join("\t", qw(?s ?p ?o)) . "\n"; 158 while (my $st = $iter->next) { 159 $string .= $self->statement_as_string( $st ); 160 } 161 } elsif (defined($e) and blessed($e) and $e->isa('RDF::Trine::VariableBindings')) { 162 my @names = $iter->binding_names; 163 $string .= join("\t", map { "?$_" } @names) . "\n"; 164 while (my $r = $iter->next) { 165 $string .= $self->result_as_string( $r, \@names ); 166 } 167 } 168 return $string; 169} 170 171sub _serialize_bounded_description { 172 my $self = shift; 173 my $model = shift; 174 my $node = shift; 175 my $seen = shift || {}; 176 # TODO: must print the header line, but only on the first (non-recursive) call to _serialize_bounded_description 177 return '' if ($seen->{ $node->sse }++); 178 my $iter = $model->get_statements( $node, undef, undef ); 179 my $string = ''; 180 while (my $st = $iter->next) { 181 my @nodes = $st->nodes; 182 $string .= $self->statement_as_string( $st ); 183 if ($nodes[2]->isa('RDF::Trine::Node::Blank')) { 184 $string .= $self->_serialize_bounded_description( $model, $nodes[2], $seen ); 185 } 186 } 187 return $string; 188} 189 190=item C<< result_as_string ( $result, \@names ) >> 191 192Returns a string with the bound terms of the given RDF::Trine::VariableBindings 193corresponding to the given C<@names> serialized in N-Triples format, separated 194by tab characters. 195 196=cut 197 198sub result_as_string { 199 my $self = shift; 200 my $r = shift; 201 my $names = shift; 202 my @terms = map { $r->{ $_ } } @$names; 203 return join("\t", map { blessed($_) ? $_->as_ntriples : '' } @terms) . "\n"; 204} 205 206=item C<< statement_as_string ( $st ) >> 207 208Returns a string with the nodes of the given RDF::Trine::Statement serialized 209in N-Triples format, separated by tab characters. 210 211=cut 212 213sub statement_as_string { 214 my $self = shift; 215 my $st = shift; 216 my @nodes = $st->nodes; 217 return join("\t", map { $_->as_ntriples } @nodes[0..2]) . "\n"; 218} 219 2201; 221 222__END__ 223 224=back 225 226=head1 BUGS 227 228Please report any bugs or feature requests to through the GitHub web interface 229at L<https://github.com/kasei/perlrdf/issues>. 230 231=head1 SEE ALSO 232 233L<http://www.w3.org/TR/rdf-testcases/#ntriples> 234 235=head1 AUTHOR 236 237Gregory Todd Williams C<< <gwilliams@cpan.org> >> 238 239=head1 COPYRIGHT 240 241Copyright (c) 2006-2012 Gregory Todd Williams. This 242program is free software; you can redistribute it and/or modify it under 243the same terms as Perl itself. 244 245=cut 246