File Coverage

blib/lib/RDF/Simple/Serialiser/NT.pm
Criterion Covered Total %
statement 13 15 86.6
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 18 20 90.0


line stmt bran cond sub pod time code
1            
2             # $Id: NT.pm,v 1.5 2009-07-04 14:29:29 Martin Exp $
3            
4             =head1 NAME
5            
6             RDF::Simple::Serialiser::NT - Output RDF triples in N-Triples format
7            
8             =head1 SYNOPSIS
9            
10             Same as L,
11             except when you call serialise(),
12             you get back a string in N-Triples format.
13            
14             =head1 PRIVATE METHODS
15            
16             =over
17            
18             =cut
19            
20             package RDF::Simple::Serialiser::NT;
21            
22 2     2   55271 use strict;
  2         4  
  2         73  
23 2     2   11 use warnings;
  2         3  
  2         53  
24            
25 2     2   2471 use Data::Dumper; # for debugging only
  2         19297  
  2         192  
26 2     2   2192 use Regexp::Common;
  2         6525  
  2         11  
27             # We need the version with the new render() method:
28 2     2   143501 use RDF::Simple::Serialiser 1.007;
  0            
  0            
29            
30             use base 'RDF::Simple::Serialiser';
31            
32             use constant DEBUG => 0;
33             use constant DEBUG_URIREF => 0;
34            
35             our
36             $VERSION = do { my @r = (q$Revision: 1.5 $ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r };
37            
38             =item render
39            
40             This method does all the N-Triples formatting.
41             Yes, it is named wrong;
42             but all other functionality is inherited from RDF::Simple::Serialiser
43             and that's how the author named the output function.
44             You won't be calling this method anyway,
45             you'll be calling the serialise() method, so what do you care!
46             In fact, I wouldn't even be telling you about it if I weren't playing the CPANTS game...
47            
48             =cut
49            
50             sub render
51             {
52             my $self = shift;
53             # Required arg1 = arrayref:
54             my $raObjects = shift;
55             # Required arg2 = hashref of namespaces:
56             my $rhNS = shift;
57             my $sRet = q{};
58             my %hsClassPrinted;
59             my $sISA = $self->_make_uriref('rdf:type', $rhNS);
60             my $sAbout = $self->_make_uriref('rdf:about', $rhNS);
61             OBJECT:
62             foreach my $object (@$raObjects)
63             {
64             DEBUG && print STDERR " DDD render object ", Dumper($object);
65             # We delete elements as we process them, so that during debugging
66             # we can see what's leftover:
67             my $sId = delete $object->{NodeId} || q{};
68             if ($sId eq q{})
69             {
70             # Item does not have a NodeId, use its Uri instead:
71             $sId = delete $object->{Uri};
72             } # if
73             my $sClass = delete $object->{Class};
74             DEBUG && print STDERR " DDD raw sId=$sId, sClass=$sClass\n";
75             $sId = $self->_make_nodeid($sId);
76             if (! $sClass)
77             {
78             print STDERR " EEE object has no Class: ", Dumper($object);
79             next OBJECT;
80             } # if
81             $sClass = $self->_make_uriref($sClass, $rhNS);
82             DEBUG && print STDERR " DDD cooked sId=$sId, sClass=$sClass\n";
83             $sRet .= qq{$sId $sISA $sClass .\n};
84             $self->{_iTriples_}++;
85             if ($object->{Uri})
86             {
87             $sRet .= qq{$sId $sAbout <$object->{Uri}> .\n};
88             $self->{_iTriples_}++;
89             delete $object->{Uri};
90             } # if
91             LITERAL:
92             foreach my $sProp (keys %{$object->{literal}})
93             {
94             LITERAL_PROPERTY:
95             foreach my $sVal (@{$object->{literal}->{$sProp}})
96             {
97             $sProp = $self->_make_uriref($sProp, $rhNS);
98             if ($sVal !~ m/\A$RE{num}{decimal}\z/)
99             {
100             # Value is non-numeric; assume it's a string and put quotes
101             # around it:
102             $sVal = qq{"$sVal"};
103             } # if
104             $sRet .= qq{$sId $sProp $sVal .\n};
105             $self->{_iTriples_}++;
106             } # foreach LITERAL_PROPERTY
107             } # foreach LITERAL
108             delete $object->{literal};
109             NODEID:
110             foreach my $sProp (keys %{$object->{nodeid}})
111             {
112             NODEID_PROPERTY:
113             foreach my $sVal (@{$object->{nodeid}->{$sProp}})
114             {
115             $sProp = $self->_make_uriref($sProp, $rhNS);
116             $sVal = $self->_make_nodeid($sVal);
117             $sRet .= qq{$sId $sProp $sVal .\n};
118             $self->{_iTriples_}++;
119             } # foreach NODEID_PROPERTY
120             } # foreach NODEID
121             delete $object->{nodeid};
122             RESOURCE:
123             foreach my $sProp (keys %{$object->{resource}})
124             {
125             RESOURCE_PROPERTY:
126             foreach my $sVal (@{$object->{resource}->{$sProp}})
127             {
128             if ($self->_looks_like_uri($sVal))
129             {
130             $sVal = qq{<$sVal>};
131             } # if
132             else
133             {
134             $sVal = $self->_make_nodeid($sVal);
135             }
136             $sProp = $self->_make_uriref($sProp, $rhNS);
137             $sRet .= qq{$sId $sProp $sVal .\n};
138             $self->{_iTriples_}++;
139             } # foreach RESOURCE_PROPERTY
140             } # foreach RESOURCE
141             delete $object->{resource};
142             print STDERR Dumper($object) if keys %$object;
143             $sRet .= qq{\n};
144             } # foreach OBJECT
145             return $sRet;
146             } # render
147            
148            
149             sub _make_nodeid
150             {
151             my $self = shift;
152             # Required arg1 = an RDF nodeID to be converted:
153             my $s = shift || q{};
154             if ($s eq q{})
155             {
156             # Need to create a (random) new ID:
157             } # if
158             $s =~ s/\A(?!_:)/_:/;
159             return $s;
160             } # _make_nodeid
161            
162             sub _make_uriref
163             {
164             my $self = shift;
165             # Required arg1 = an RDF element to be converted:
166             my $s = shift || q{};
167             DEBUG_URIREF && print STDERR " DDD _make_uriref($s)\n";
168             # Required arg2 = hashref of namespaces:
169             my $rhNS = shift;
170             DEBUG_URIREF && print STDERR " DDD rhNS is ", Dumper($rhNS);
171             my $sClass;
172             my $sNS = 'base';
173             if ($s =~ m/\A([^:]*):([^:]+)\z/)
174             {
175             DEBUG_URIREF && print STDERR " DDD found ns=$1, val=$2\n";
176             # Class is explicitly qualified with a "prefix:", ergo now
177             # explicitly qualify it in that namespace:
178             $sNS = $1 || 'base';
179             $sClass = $2;
180             } # if
181             else
182             {
183             # Input string does not contain a colon. What is it?
184             return $s;
185             }
186             $s = qq{<$rhNS->{$sNS}$sClass>};
187             return $s;
188             } # _make_uriref
189            
190            
191             =back
192            
193             =head1 PUBLIC METHODS
194            
195             =over
196            
197             =item get_triple_count
198            
199             Returns the number of triples created since the last call to
200             reset_triple_count().
201            
202             =cut
203            
204             sub get_triple_count
205             {
206             my $self = shift;
207             return $self->{_iTriples_};
208             } # get_triple_count
209            
210            
211             =item reset_triple_count
212            
213             Resets the internal counter of triples to zero.
214            
215             =cut
216            
217             sub reset_triple_count
218             {
219             my $self = shift;
220             $self->{_iTriples_} = 0;
221             } # get_triple_count
222            
223             1;
224            
225             __END__