File Coverage

blib/lib/SOAP/ISIWoK.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package SOAP::ISIWoK;
2              
3 1     1   34866 use SOAP::Lite;
  0            
  0            
4             use HTTP::Cookies;
5             use MIME::Base64;
6             #use SOAP::Lite +'trace';
7              
8             use 5.008000;
9             use strict;
10             use warnings;
11              
12             our @ISA = qw();
13              
14             our $VERSION = '3.01';
15              
16             use constant {
17             AUTHENTICATE_ENDPOINT => 'http://search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate',
18             AUTHENTICATE_NS => 'http://auth.cxf.wokmws.thomsonreuters.com',
19              
20             WOKSEARCH_ENDPOINT => 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearch',
21             WOKSEARCH_LITE_ENDPOINT => 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearchLite',
22              
23             WOKSEARCH_NS => 'http://woksearch.cxf.wokmws.thomsonreuters.com',
24              
25             WOKSEARCH_SERVICE_TYPE => 'woksearch',
26             WOKSEARCH_LITE_SERVICE_TYPE => 'woksearchlite',
27             };
28              
29             use constant {
30             QUERY_LANGUAGE => 'en',
31             };
32              
33             =head1 NAME
34              
35             SOAP::ISIWoK - interogate the ISI WoS database
36              
37             =head1 SYNOPSIS
38              
39             use SOAP::ISIWoK;
40              
41             $wos = SOAP::ISIWoK->new;
42            
43             $som = $wos->authenticate;
44             die $som->faultstring if $som->fault;
45              
46             $som = $wos->search('AU = (Brody)');
47              
48             =head1 DESCRIPTION
49              
50             Search and retrieve records from the Thomson Reuters ISI Web of Knowledge
51             database.
52              
53             This module is NOT backwards compatible with SOAP::ISIWoK 1.xx (deprecated WoK
54             API). Significant changes:
55              
56             - you must now authenticate with WoK to get a session id
57             - methods now return SOAP::Lite objects, use your favourite XML parser to
58             parse $som->result->{records} or
59             - throw an error on $som->fault
60              
61             =head2 Editions
62              
63             Select which editions to query. Some editions may not be available, depending on your WoS subscription.
64              
65             =over 4
66              
67             =item SCI
68              
69             Science Citation Index Expanded
70              
71             =item SSCI
72              
73             Social Sciences Citation Index
74              
75             =item AHCI
76              
77             Arts & Humanities Citation Index
78              
79             =item ISTP
80              
81             Conference Proceedings Citation Index - Science
82              
83             =item ISSHP
84              
85             Conference Proceedings Citation Index - Social Sciences
86              
87             =item IC
88              
89             Index Chemicus
90              
91             =item CCR
92              
93             Current Chemical Reactions
94              
95             =item BSCI
96              
97             Book Citation Index - Science
98              
99             =item BHCI
100              
101             Book Citation Index - Social Sciences and Humanities
102              
103             =back
104              
105             =head2 Sort Fields
106              
107             Sort results by the given field. Only relevance and times-cited may be reverse sorted, by specifying '-' in front of the sort name.
108              
109             =over 4
110              
111             =item AU
112              
113             Author
114              
115             =item CF
116              
117             Conference Title
118              
119             =item CG
120              
121             Page
122              
123             =item CW
124              
125             Source
126              
127             =item CV
128              
129             Volume
130              
131             =item CY
132              
133             Publication Year
134              
135             =item LC
136              
137             Local Times Cited
138              
139             =item LD
140              
141             Load Date
142              
143             =item PG
144              
145             Page
146              
147             =item PY
148              
149             Publication Year
150              
151             =item RS / -RS
152              
153             Relevance
154              
155             =item SO
156              
157             Source
158              
159             =item TC / -TC
160              
161             Times Cited
162              
163             =item VL
164              
165             Volume
166              
167             =back
168              
169              
170             =head2 Required Fields
171              
172             Only return records that contain the given field(s). For example:
173              
174             fields => [qw(
175             address_spec
176             category_info
177             )],
178              
179             is logically equivalent to only showing records that contain:
180              
181             (Publisher City OR Publisher Address)
182             AND
183             (Web of Science Category OR Subject Category)
184              
185             =over 4
186              
187             =item pub_info
188              
189             Publication Type (J=Journal; B=Book; S=Series)
190              
191             =item names
192              
193             Authors, Book Authors, Group Authors, Book Group Authors, ResearcherID Number, Editors, Publisher
194              
195             =item full_name
196              
197             Author Full Name
198              
199             =item titles
200              
201             Publication Name, Book Series Title, Book Series Subtitle, 29-Character Source Abbreviation, ISO Source Abbreviation
202              
203             =item language
204              
205             Language
206              
207             =item doctypes
208              
209             Document Type
210              
211             =item conf_title
212              
213             Conference Title
214              
215             =item conf_date
216              
217             Conference Date
218              
219             =item conf_host
220              
221             Conference Host
222              
223             =item conf_locations
224              
225             Conference Location
226              
227             =item sponsors
228              
229             Conference Sponsors
230              
231             =item keywords
232              
233             Author Keywords
234              
235             =item keywords_plus
236              
237             Keywords Plus
238              
239             =item abstract
240              
241             Abstract
242              
243             =item addresses
244              
245             Author Address
246              
247             =item reprint_contact
248              
249             Reprint Address
250              
251             =item email_addr
252              
253             E-mail Address
254              
255             =item grant
256              
257             Funding Agency and Grant Number
258              
259             =item fund_text
260              
261             Funding Text
262              
263             =item refs
264              
265             Cited Reference Count
266              
267             =item address_spec
268              
269             Publisher City, Publisher Address
270              
271             =item category_info
272              
273             Web of Science Category, Subject Category
274              
275             =item identifiers
276              
277             International Standard Serial Number (ISSN), International Standard Book Number (ISBN), Book Digital Object Identifier (DOI), Article Number, Digital Object Identifier (DOI)
278              
279             =item pub_info
280              
281             Publication Date, Year Published, Volume, Issue, Part Number, Supplement, Special Issue
282              
283             =item page
284              
285             Beginning Page, Ending Page, Page Count
286              
287             =item book_chapters
288              
289             Chapter Count in a Book
290              
291             =item ids
292              
293             Document Delivery Number
294              
295             =item UID
296              
297             Accession Number
298              
299             =back
300              
301              
302             =head2 Options
303              
304             options => {
305             RecordIDs => 'On',
306             },
307              
308             =over 4
309              
310             =item RecordIDs
311              
312             On
313             Off
314              
315             Return the UIDs of records as SOAP data.
316              
317             =back
318              
319             =head1 METHODS
320              
321             =over 4
322              
323             =cut
324              
325             # Preloaded methods go here.
326              
327             =item $wos = SOAP::ISIWoK->new( [ OPTIONS ] )
328              
329             Options:
330              
331             =over 4
332              
333             =item database = WOK
334              
335             Database to search (WOK = all database).
336              
337             =item collections = { WOS => [] }
338              
339             BIOABS, BCI, BIOSIS, CABI, CSCD, CCC, DIIDW, FSTA, INSPEC, MEDLINE, WOS,
340             ZOOREC
341              
342             The key is the Collection to search (WOS = Web of Science) and the value is a list of editions within that collection.
343              
344             See Web Service documentation for the available editions, otherwise an empty array will search all editions that you are subscribed to.
345              
346             =back
347              
348             =cut
349              
350             sub new
351             {
352             my ($class, %self) = @_;
353              
354             $self{cookie_jar} ||= HTTP::Cookies->new(ignore_discard => 1);
355             $self{endpoint} ||= WOKSEARCH_ENDPOINT;
356             $self{service_type} ||= WOKSEARCH_SERVICE_TYPE;
357             $self{database} ||= 'WOK';
358             $self{collections} ||= { WOS => [] };
359              
360             my $self = bless \%self, $class;
361              
362             return $self;
363             }
364              
365             sub DESTROY
366             {
367             shift->closeSession;
368             }
369              
370             # this suppreses the usual xsi:nil="true" attribute, which WoS rejects
371             sub SOAP::Serializer::as_nonil
372             {
373             my ($self, $value, $name, $type, $attr) = @_;
374             delete $attr->{'xsi:nil'};
375             return [ $name, $attr, $value ];
376             }
377              
378             =item $som = $wos->authenticate([$username, $password])
379              
380             die $som->faultstring if $som->fault;
381             print "Session ID: ".$som->result;
382              
383             Get a WoS session ID.
384              
385             =cut
386              
387             sub authenticate
388             {
389             my ($self, $username, $password) = @_;
390              
391             my $soap = SOAP::Lite->new(
392             proxy => AUTHENTICATE_ENDPOINT,
393             );
394              
395             $soap->transport->cookie_jar($self->{cookie_jar});
396              
397             if (defined $username) {
398             $password = '' if !defined $password;
399             $soap->transport->http_request->header(
400             Authorization => "Basic ".MIME::Base64::encode_base64("$username:$password")
401             );
402             }
403              
404             my $som = $soap->call( SOAP::Data->new(
405             type => 'nonil', # custom type
406             name => 'authenticate',
407             prefix => '',
408             uri => AUTHENTICATE_NS,
409             ));
410              
411             $self->{sid} = $som->result if !$som->fault;
412              
413             return $som;
414             }
415              
416             =item $som = $wos->closeSession()
417              
418             Explicitly close the session with WoS. Otherwise is called when this object goes out of scope.
419              
420             =cut
421              
422             sub closeSession
423             {
424             my ($self) = @_;
425              
426             return if !$self->{sid};
427              
428             my $soap = SOAP::Lite->new(
429             proxy => AUTHENTICATE_ENDPOINT,
430             );
431              
432             $soap->transport->cookie_jar($self->{cookie_jar});
433              
434             my $som = $soap->call( SOAP::Data->new(
435             type => 'nonil', # custom type
436             name => 'closeSession',
437             prefix => '',
438             uri => AUTHENTICATE_NS,
439             ));
440              
441             undef $self->{sid};
442              
443             return $som;
444             }
445              
446             sub _retrieveParameters
447             {
448             my ($self, %opts) = @_;
449              
450             $opts{offset} = 0 if !defined $opts{offset};
451             $opts{max} = 10 if !defined $opts{max};
452             $opts{fields} = [] if !exists $opts{fields};
453             $opts{options} = {} if !exists $opts{options};
454              
455             my @rparams = (
456             SOAP::Data->name( firstRecord => $opts{offset}+1 ),
457             SOAP::Data->name( count => $opts{max} ),
458             );
459              
460             if ($opts{sort}) {
461             my $sort = $opts{sort};
462             my $order = $sort =~ s/^-// ? 'D' : 'A';
463             push @rparams, SOAP::Data->name( sortField => \SOAP::Data->value(
464             SOAP::Data->name( name => $sort ),
465             SOAP::Data->name( sort => $order ),
466             ) );
467             }
468              
469             if ($opts{fields} && @{$opts{fields}}) {
470             push @rparams, SOAP::Data->name( viewField => \SOAP::Data->value(
471             SOAP::Data->name( collectionName => 'WOS' ), # WOS only valid collectionName ???
472             map {
473             SOAP::Data->name( fieldName => $_ )
474             } @{$opts{fields}}
475             ) );
476             }
477              
478             foreach my $key (sort keys %{$opts{options}})
479             {
480             push @rparams, SOAP::Data->name( option => [
481             SOAP::Data->name(key => $key),
482             SOAP::Data->name(value => $opts{options}{$key}),
483             ]);
484             }
485              
486             return @rparams;
487             }
488              
489             sub soap
490             {
491             my ($self) = @_;
492              
493             my $soap = SOAP::Lite->new(
494             proxy => $self->{endpoint},
495             autotype => 0,
496             );
497              
498             $soap->transport->cookie_jar($self->{cookie_jar});
499              
500             return $soap;
501             }
502              
503             =item $som = $wos->citedReferences($uid [, OPTIONS ])
504              
505             =cut
506              
507             sub citedReferences
508             {
509             my ($self, $q, %opts) = @_;
510              
511             my $service = $self->{service_type};
512              
513             my $som = $self->soap->call(
514             SOAP::Data->new(
515             name => "$service:citedReferences",
516             attr => {
517             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
518             },
519             ),
520             SOAP::Data->name(databaseId => $self->{database}),
521             SOAP::Data->name(uid => $q),
522             SOAP::Data->name(queryLanguage => QUERY_LANGUAGE),
523             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
524             );
525              
526             return _fix_records($som);
527             }
528              
529             =item $som = $wos->citedReferencesRetrieve($queryId [, OPTIONS ])
530              
531             =cut
532              
533             sub citedReferencesRetrieve
534             {
535             my ($self, $q, %opts) = @_;
536              
537             my $service = $self->{service_type};
538              
539             my $som = $self->soap->call(
540             SOAP::Data->new(
541             name => "$service:citedReferencesRetrieve",
542             attr => {
543             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
544             },
545             ),
546             SOAP::Data->name(queryId => $q),
547             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
548             );
549              
550             return _fix_records($som);
551             }
552              
553             sub _related
554             {
555             my ($self, $method, $q, %opts) = @_;
556              
557             my $service = $self->{service_type};
558              
559             my @qparams;
560              
561             push @qparams, SOAP::Data->name(databaseId => $self->{database});
562              
563             push @qparams, SOAP::Data->name(uid => $q);
564              
565             foreach my $collection (sort keys %{$self->{collections}}) {
566             foreach my $edition (sort @{$self->{collections}{$collection}}) {
567             push @qparams, SOAP::Data->name(editions => \SOAP::Data->value(
568             SOAP::Data->name(collection => $collection),
569             SOAP::Data->name(edition => $edition),
570             ) );
571             }
572             }
573              
574             if ($opts{begin} || $opts{end}) {
575             push @qparams, SOAP::Data->name( timeSpan => \SOAP::Data->value(
576             SOAP::Data->name(begin => $opts{begin}),
577             SOAP::Data->name(end => $opts{end}),
578             ) );
579             }
580              
581             push @qparams, SOAP::Data->name(queryLanguage => QUERY_LANGUAGE);
582              
583             my $som = $self->soap->call(
584             SOAP::Data->new(
585             name => "$service:$method",
586             attr => {
587             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
588             },
589             ),
590             @qparams,
591             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
592             );
593              
594             return _fix_records($som);
595             }
596              
597             =item $som = $wos->citingArticles($uid [, OPTIONS ])
598              
599             =cut
600              
601             sub citingArticles
602             {
603             my ($self, $q, %opts) = @_;
604              
605             return $self->_related('citingArticles', $q, %opts);
606             }
607              
608             =item $som = $wos->relatedRecords($uid [, OPTIONS ])
609              
610             =cut
611              
612             sub relatedRecords
613             {
614             my ($self, $q, %opts) = @_;
615              
616             return $self->_related('relatedRecords', $q, %opts);
617             }
618              
619             =item $som = $wos->retrieve($queryId [, OPTIONS ])
620              
621             =cut
622              
623             sub retrieve
624             {
625             my ($self, $q, %opts) = @_;
626              
627             $opts{sort} = '-RS' if !exists $opts{sort};
628              
629             my $service = $self->{service_type};
630              
631             my $som = $self->soap->call(
632             SOAP::Data->new(
633             name => "$service:retrieve",
634             attr => {
635             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
636             },
637             ),
638             SOAP::Data->name(queryId => $q),
639             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
640             );
641              
642             return _fix_records($som);
643             }
644              
645             =item $som = $wos->retrieveById(UIDs [, OPTIONS])
646              
647             UIDs is an array ref of uids.
648              
649             =cut
650              
651             sub retrieveById
652             {
653             my ($self, $q, %opts) = @_;
654              
655             $q = [$q] if ref($q) ne "ARRAY";
656              
657             my $service = $self->{service_type};
658              
659             my @qparams;
660              
661             push @qparams, SOAP::Data->name(databaseId => $self->{database});
662              
663             push @qparams, map {
664             SOAP::Data->name(uid => $_)
665             } @$q;
666              
667             push @qparams, SOAP::Data->name(queryLanguage => QUERY_LANGUAGE);
668              
669             my $som = $self->soap->call(
670             SOAP::Data->new(
671             name => "$service:retrieveById",
672             attr => {
673             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
674             },
675             ),
676             @qparams,
677             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
678             );
679              
680             return _fix_records($som);
681             }
682              
683             =item $som = $wos->search($query [, OPTIONS])
684              
685             Options:
686              
687             =over 4
688              
689             =item begin - YYYY-MM-DD
690              
691             =item end - YYYY-MM-DD
692              
693             =item offset = 0
694              
695             =item max = 10
696              
697             =item sort = -RS
698              
699             See L.
700              
701             =item fields = []
702              
703             See L.
704              
705             =item options = {}
706              
707             See L
708              
709             =back
710              
711             =cut
712              
713             sub search
714             {
715             my ($self, $q, %opts) = @_;
716              
717             $opts{sort} = '-RS' if !exists $opts{sort};
718              
719             my @qparams;
720              
721             push @qparams, SOAP::Data->name(databaseId => $self->{database});
722              
723             push @qparams, SOAP::Data->name(userQuery => $q);
724              
725             foreach my $collection (sort keys %{$self->{collections}}) {
726             foreach my $edition (sort @{$self->{collections}{$collection}}) {
727             push @qparams, SOAP::Data->name(editions => \SOAP::Data->value(
728             SOAP::Data->name(collection => $collection),
729             SOAP::Data->name(edition => $edition),
730             ) );
731             }
732             }
733              
734             if ($opts{begin} || $opts{end}) {
735             push @qparams, SOAP::Data->name( timeSpan => \SOAP::Data->value(
736             SOAP::Data->name(begin => $opts{begin}),
737             SOAP::Data->name(end => $opts{end}),
738             ) );
739             }
740              
741             push @qparams, SOAP::Data->name(queryLanguage => QUERY_LANGUAGE);
742              
743             my $service = $self->{service_type};
744              
745             my $som = $self->soap->call(
746             SOAP::Data->new(
747             name => "$service:search",
748             attr => {
749             "xmlns:$service" => "http://$service.v3.wokmws.thomsonreuters.com",
750             },
751             ),
752             SOAP::Data->name(queryParameters => \SOAP::Data->value(@qparams)),
753             SOAP::Data->name(retrieveParameters => \SOAP::Data->value($self->_retrieveParameters(%opts))),
754             );
755              
756             return _fix_records($som);
757             }
758              
759             sub _fix_records
760             {
761             my ($som) = @_;
762              
763             # attribute is sometimes repeated, so lets fix
764             # that for the consuming user
765             if (defined $som->result && exists $som->result->{records}) {
766             $som->result->{records} =~ s/r_id_disclaimer="[^"]+"//g;
767             }
768              
769             return $som;
770             }
771              
772             1;
773             __END__