File Coverage

blib/lib/RDF/Simple/Serialiser/NT.pm
Criterion Covered Total %
statement 91 106 85.8
branch 9 16 56.2
condition 4 8 50.0
subroutine 12 13 92.3
pod 3 3 100.0
total 119 146 81.5


line stmt bran cond sub pod time code
1            
2             # $Id: NT.pm,v 1.6 2010-12-02 23:41:57 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 1     1   85376 use strict;
  1         12  
  1         31  
23 1     1   5 use warnings;
  1         2  
  1         25  
24            
25 1     1   792 use Data::Dumper; # for debugging only
  1         7356  
  1         67  
26 1     1   601 use Regexp::Common;
  1         2737  
  1         4  
27             # We need the version with the new render() method:
28 1     1   165581 use RDF::Simple::Serialiser 1.007;
  1         37200  
  1         37  
29            
30 1     1   8 use base 'RDF::Simple::Serialiser';
  1         2  
  1         104  
31            
32 1     1   7 use constant DEBUG => 0;
  1         2  
  1         53  
33 1     1   7 use constant DEBUG_URIREF => 0;
  1         4  
  1         1354  
34            
35             our
36             $VERSION = do { my @r = (q$Revision: 1.6 $ =~ /\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 1     1 1 5090 my $self = shift;
53             # Required arg1 = arrayref:
54 1         3 my $raObjects = shift;
55             # Required arg2 = hashref of namespaces:
56 1         2 my $rhNS = shift;
57 1         2 my $sRet = q{};
58 1         2 my %hsClassPrinted;
59 1         13 my $sISA = $self->_make_uriref('rdf:type', $rhNS);
60 1         4 my $sAbout = $self->_make_uriref('rdf:about', $rhNS);
61             OBJECT:
62 1         4 foreach my $object (@$raObjects)
63             {
64 2         3 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 2   50     13 my $sId = delete $object->{NodeId} || q{};
68 2 50       6 if ($sId eq q{})
69             {
70             # Item does not have a NodeId, use its Uri instead:
71 2         5 $sId = delete $object->{Uri};
72             } # if
73 2         6 my $sClass = delete $object->{Class};
74 2         3 DEBUG && print STDERR " DDD raw sId=$sId, sClass=$sClass\n";
75 2         6 $sId = $self->_make_nodeid($sId);
76 2 50       7 if (! $sClass)
77             {
78 0         0 print STDERR " EEE object has no Class: ", Dumper($object);
79 0         0 next OBJECT;
80             } # if
81 2         6 $sClass = $self->_make_uriref($sClass, $rhNS);
82 2         3 DEBUG && print STDERR " DDD cooked sId=$sId, sClass=$sClass\n";
83 2         8 $sRet .= qq{$sId $sISA $sClass .\n};
84 2         5 $self->{_iTriples_}++;
85 2 50       6 if ($object->{Uri})
86             {
87 0         0 $sRet .= qq{$sId $sAbout <$object->{Uri}> .\n};
88 0         0 $self->{_iTriples_}++;
89 0         0 delete $object->{Uri};
90             } # if
91             LITERAL:
92 2         5 foreach my $sProp (keys %{$object->{literal}})
  2         8  
93             {
94             LITERAL_PROPERTY:
95 5         7 foreach my $sVal (@{$object->{literal}->{$sProp}})
  5         12  
96             {
97 5         12 $sProp = $self->_make_uriref($sProp, $rhNS);
98 5 100       22 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 3         345 $sVal = qq{"$sVal"};
103             } # if
104 5         442 $sRet .= qq{$sId $sProp $sVal .\n};
105 5         17 $self->{_iTriples_}++;
106             } # foreach LITERAL_PROPERTY
107             } # foreach LITERAL
108 2         8 delete $object->{literal};
109             NODEID:
110 2         4 foreach my $sProp (keys %{$object->{nodeid}})
  2         8  
111             {
112             NODEID_PROPERTY:
113 0         0 foreach my $sVal (@{$object->{nodeid}->{$sProp}})
  0         0  
114             {
115 0         0 $sProp = $self->_make_uriref($sProp, $rhNS);
116 0         0 $sVal = $self->_make_nodeid($sVal);
117 0         0 $sRet .= qq{$sId $sProp $sVal .\n};
118 0         0 $self->{_iTriples_}++;
119             } # foreach NODEID_PROPERTY
120             } # foreach NODEID
121 2         5 delete $object->{nodeid};
122             RESOURCE:
123 2         6 foreach my $sProp (keys %{$object->{resource}})
  2         6  
124             {
125             RESOURCE_PROPERTY:
126 1         4 foreach my $sVal (@{$object->{resource}->{$sProp}})
  1         4  
127             {
128 1 50       6 if ($self->_looks_like_uri($sVal))
129             {
130 0         0 $sVal = qq{<$sVal>};
131             } # if
132             else
133             {
134 1         133 $sVal = $self->_make_nodeid($sVal);
135             }
136 1         8 $sProp = $self->_make_uriref($sProp, $rhNS);
137 1         6 $sRet .= qq{$sId $sProp $sVal .\n};
138 1         3 $self->{_iTriples_}++;
139             } # foreach RESOURCE_PROPERTY
140             } # foreach RESOURCE
141 2         4 delete $object->{resource};
142 2 50       8 print STDERR Dumper($object) if keys %$object;
143 2         5 $sRet .= qq{\n};
144             } # foreach OBJECT
145 1         4 return $sRet;
146             } # render
147            
148            
149             sub _make_nodeid
150             {
151 3     3   7 my $self = shift;
152             # Required arg1 = an RDF nodeID to be converted:
153 3   50     8 my $s = shift || q{};
154 3 50       8 if ($s eq q{})
155             {
156             # Need to create a (random) new ID:
157             } # if
158 3         12 $s =~ s/\A(?!_:)/_:/;
159 3         7 return $s;
160             } # _make_nodeid
161            
162             sub _make_uriref
163             {
164 10     10   16 my $self = shift;
165             # Required arg1 = an RDF element to be converted:
166 10   50     24 my $s = shift || q{};
167 10         16 DEBUG_URIREF && print STDERR " DDD _make_uriref($s)\n";
168             # Required arg2 = hashref of namespaces:
169 10         20 my $rhNS = shift;
170 10         14 DEBUG_URIREF && print STDERR " DDD rhNS is ", Dumper($rhNS);
171 10         15 my $sClass;
172 10         15 my $sNS = 'base';
173 10 50       45 if ($s =~ m/\A([^:]*):([^:]+)\z/)
174             {
175 10         14 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 10   50     33 $sNS = $1 || 'base';
179 10         16 $sClass = $2;
180             } # if
181             else
182             {
183             # Input string does not contain a colon. What is it?
184 0         0 return $s;
185             }
186 10         31 $s = qq{<$rhNS->{$sNS}$sClass>};
187 10         22 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 1     1 1 787 my $self = shift;
207 1         6 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 0     0 1   my $self = shift;
220 0           $self->{_iTriples_} = 0;
221             } # get_triple_count
222            
223             1;
224            
225             __END__