File Coverage

blib/lib/MODS/Record.pm
Criterion Covered Total %
statement 565 795 71.0
branch 0 70 0.0
condition 0 26 0.0
subroutine 189 288 65.6
pod 0 7 0.0
total 754 1186 63.5


line stmt bran cond sub pod time code
1             package MODS::Record;
2              
3             =head1 NAME
4              
5             MODS::Record - Perl extension for handling MODS records
6              
7             =head1 SYNOPSIS
8              
9             use MODS::Record qw(xml_string);
10             use open qw(:utf8);
11              
12             my $mods = MODS::Record->new;
13              
14             my $collection = MODS::Collection->new;
15              
16             my $mods = $collection->add_mods(ID => '1234');
17              
18             $mods->add_abstract("Hello", lang => 'eng');
19             $mods->add_abstract("Bonjour", lang => 'fra');
20              
21             # Set a deeply nested field...
22             $mods->add_language()->add_languageTerm('eng');
23              
24             # Set a list of deeply nested fields...
25             $mods->add_location(sub {
26             $_[0]->add_physicalLocation('here');
27             $_[0]->add_shelfLocator('here too');
28             $_[0]->add_url('http://here.org/there');
29             });
30              
31             # Set an inline XML extension...
32             $mods->add_accessCondition(xml_string("21212"));
33              
34             # Retrieve a field by a filter...
35             $mods->get_abstract(lang => 'fra')->body("Bonjour :)");
36             $mods->get_abstract(lang => 'fra')->contentType('text/plain');
37              
38             for ($mods->get_abstract(lang => 'fra')) {
39             printf "%s\n" , $_->body;
40             }
41              
42             # Set a field to a new value
43             my @newabstract;
44             for ($mods->get_abstract) {
45             push @newabstract, $_ unless $_->lang eq 'fra';
46             }
47             $mods->set_abstract(@newabstract);
48              
49             # Clear all abstracts;
50             $mods->set_abstract(undef);
51              
52             # Serialize
53             print $mods->as_json(pretty => 1);
54             print $mods->as_xml;
55              
56             # Deserialize
57             my $mods = MODS::Record->from_xml(IO::File->new('mods.xml'));
58             my $mods = MODS::Record->from_json(IO::File->new('mods.js'));
59              
60             my $count = MODS::Record->from_xml(IO::File->new('mods.xml'), sub {
61             my $mods = shift;
62             ...
63             });
64              
65             my $count = MODS::Record->from_json(IO::File->new('mods.js'), sub {
66             my $mods = shift;
67             ...
68             });
69              
70             =head1 DESCRIPTION
71              
72             This module provides MODS (http://www.loc.gov/standards/mods/) parsing and creation for MODS Schema 3.5.
73              
74             =head1 METHODS
75              
76             =head2 MODS::Record->new(%attribs)
77              
78             =head2 MODS::Collection->new(%attribs)
79              
80             Create a new MODS record or collection. Optionally attributes can be provided as
81             defined by the MODS specification. E.g.
82              
83             $mods = MODS::Record->new(ID='123');
84              
85             =head2 add_xxx()
86              
87             Add a new element to the record where 'xxx' is the name of a MODS element (e.g. titleInfo, name, genre, etc).
88             This method returns an instance of the added MODS element. E.g.
89              
90             $titleInfo = $mods->add_titleInfo; # $titleInfo is a 'MODS::Element::TitleInfo'
91              
92             =head2 add_xxx($text,%attribs)
93              
94             Add a new element to the record where 'xxx' is the name of a MODS element. Set the text content of the element to $text
95             and optionally provide further attributes. This method returns an instance of the added MODS element. E.g.
96              
97             $mods->add_abstract("My abstract", lang=>'eng');
98              
99             =head2 add_xxx(sub { })
100              
101             Add a new element to the record where 'xxx' is the name of a MODS element. The provided coderef gets as input an instance
102             of the added MODS element. This method returns an instance of the added MODS element. E.g.
103              
104             $mods->add_abstract(sub {
105             my $o = shift;
106             $o->body("My abstract");
107             $o->lang("eng");
108             })
109              
110             =head2 add_xxx($obj)
111              
112             Add a new element to the record where 'xxx' is the name of a MODS element. The $obj is an instance of a MODS::Element::Xxx
113             class (where Xxx is the corresponding MODS element). This method returns an instance of the added MODS element. E.g.
114              
115             $mods->add_abstract(
116             MODS::Element::Abstract->new(_body=>'My abstract', lang=>'eng')
117             );
118              
119             =head2 get_xxx()
120              
121             =head2 get_xxx(%filter)
122              
123             =head2 get_xxx(sub { })
124              
125             Retrieve an element from the record where 'xxx' is the name of a MODS element. This methods return in array context all the
126             matching elements or the first match in scalar context. Optionally provide a %filter or a coderef filter function.
127             E.g.
128              
129             @titles = $mods->get_titleInfo();
130             $alt = $mods->get_titleInfo(type=>'alternate');
131             $alt = $mods->get_titleInfo(sub { shift->type eq 'alternate'});
132              
133             =head2 set_xxxx()
134              
135             =head2 set_xxx(undef)
136              
137             =head2 set_xxx($array_ref)
138              
139             =head2 set_xxx($xxx1,$xxx2,...)
140              
141             Set an element of the record to a new value where 'xxx' is the name of a MODS element. When no arguments are provided, then this
142             is a null operation. When undef als argument is provided, then the element is deleted. To overwrite the existing content of the
143             element an ARRAY (ref) of MODS::Element::Xxx can be provided (where 'Xxx' is the corresponding MODS element). E.g.
144              
145             # Delete all abstracts
146             $mods->set_abstract(undef);
147              
148             # Set all abstracts
149             $mods->set_abstract(MODS::Element::Abstract->new(), MODS::Element::Abstract->new(), ...);
150             $mods->set_abstract([ MODS::Element::Abstract->new(), MODS::Element::Abstract->new(), ... ]);
151              
152             =head2 as_xml()
153              
154             =head2 as_xml(xml_prolog=>1)
155              
156             Return the record as XML.
157              
158             =head2 from_xml($string [, $callback])
159              
160             =head2 from_xml(IO::Handle [, $callback])
161              
162             Parse an XML string or IO::Handle into a MODS::Record. This method return the parsed JSON.
163              
164             If a callback function is provided then for each MODS element in the XML stream the callback will be called.
165             The method returns the number of parsed MODS elements.
166              
167             E.g.
168             my $mods = MODS::Record->from_xml( IO::File->new(...) );
169              
170             my $count = MODS::Record->from_xml( IO::File->new(...) , sub {
171             my $mods = shift;
172             } );
173              
174             =head2 as_json()
175              
176             =head2 as_json(pretty=>1)
177              
178             Return the record as JSON string.
179              
180             =head2 from_json($string [, $callback])
181              
182             =head2 from_json(IO::Handle [, $callback])
183              
184             Parse and JSON string or JSON::Handle into a MODS::Record. This method return the parsed JSON.
185              
186             If a callback function is provided then we expect as input a stream of JSON strings
187             (each line one JSON string). For each MODS object in the JSON stream the callback will be called.
188             The method returns the number of parsed strings.
189              
190             E.g.
191             my $mods = MODS::Record->from_json( IO::File->new(...) );
192              
193             my $count = MODS::Record->from_json( IO::File->new(...) , sub {
194             my $mods = shift;
195             } );
196              
197             =head1 SEE ALSO
198              
199             =over 4
200              
201             =item * Library Of Congress MODS pages (http://www.loc.gov/standards/mods/)
202              
203             =back
204              
205             =head1 DESIGN NOTES
206              
207             =over 4
208              
209             =item * I'm not a MODS expert
210              
211             =item * I needed a MODS module to parse and create MODS records for our institutional repository
212              
213             =item * This module is part of the LibreCat/Catmandu project http://librecat.org
214              
215             =item * This module is not created for speed
216              
217             =item * This module doesn't have any notion of ordering of MODS elements themselves (e.g. first 'titleInfo', then 'name').
218             But each sub-element keeps its original order (e.g. each 'title' in 'titleInfo').
219              
220             =item * Heiko Jansen provides at GitHub a Moose-based MODS parser https://github.com/heikojansen/MODS--Record
221              
222             =back
223              
224             =head1 AUTHORS
225              
226             =over 4
227              
228             =item * Patrick Hochstenbach
229              
230             =back
231              
232             =head1 LICENSE
233              
234             This library is free software and may be distributed under the same terms
235             as perl itself. See L.
236              
237             =cut
238              
239 2     2   42033 use vars qw( $VERSION );
  2         4  
  2         110  
240             $VERSION = '0.11';
241              
242 2     2   11 use Exporter;
  2         5  
  2         424  
243             our @ISA = qw(Exporter);
244             our @EXPORT_OK = qw(xml_string);
245              
246             sub new {
247 0     0     my ($class,@opts) = @_;
248              
249 0           return MODS::Element::Mods->new(@opts);
250             }
251              
252             sub from_xml {
253 0     0     my ($self,@opts) = @_;
254 0           MODS::Parser->new->parse(@opts);
255             }
256              
257             sub from_json {
258 0     0     my ($self,@opts) = @_;
259 0           MODS::Parser->new->parse_json(@opts);
260             }
261              
262             sub xml_string {
263 0     0     my $string = shift;
264 0           return MODS::Record::Xml_String->new(_body => $string);
265             }
266              
267             package MODS::Collection;
268              
269 2     2   8 use Exporter;
  2         17  
  2         430  
270             our @ISA = qw(Exporter);
271             our @EXPORT_OK = qw(xml_string);
272              
273             sub new {
274 0     0     my ($class,@opts) = @_;
275              
276 0           return MODS::Element::ModsCollection->new(@opts);
277             }
278              
279             sub from_xml {
280 0     0     my ($self,@opts) = @_;
281 0           MODS::Parser->new->parse(@opts);
282             }
283              
284             sub from_json {
285 0     0     my ($self,@opts) = @_;
286 0           MODS::Parser->new->parse_json(@opts);
287             }
288              
289             sub xml_string {
290 0     0     my $string = shift;
291 0           return MODS::Record::Xml_String->new(_body => $string);
292             }
293              
294              
295             package MODS::Record::Util;
296              
297 2     2   5998 use Moo::Role;
  2         87947  
  2         12  
298 2     2   722 use Carp;
  2         5  
  2         137  
299 2     2   2080 use JSON;
  2         48575  
  2         11  
300              
301             sub AUTOLOAD {
302 0     0     my ($self,@args) = @_;
303              
304 0           my ($meth) = (our $AUTOLOAD =~ /([^:]+)$/);
305              
306 0 0         if ($meth =~ /^add_(\w+)/) {
    0          
    0          
307 0           my ($attrib) = $1;
308              
309 0 0         die "no such method $attrib" unless $self->can($attrib);
310              
311 0           return $self->_adder($attrib,@args);
312             }
313             elsif ($meth =~ /^get_(\w+)/) {
314 0           my ($attrib) = $1;
315              
316 0 0         die "no such method $attrib" unless $self->can($attrib);
317              
318 0           return $self->_getter($attrib,@args);
319             }
320             elsif ($meth =~ /^set_(\w+)/) {
321 0           my ($attrib) = $1;
322              
323 0 0         die "no such method $attrib" unless $self->can($attrib);
324              
325 0           return $self->_setter($attrib,@args);
326             }
327             }
328              
329             sub escape {
330 0     0 0   my $str = shift;
331 0 0         return "" unless defined $str;
332 0           $str =~ s{&}{&}g;
333 0           $str =~ s{"}{"}g;
334 0           $str =~ s{'}{'}g;
335 0           $str =~ s{<}{<}g;
336 0           $str =~ s{>}{>}g;
337 0           $str;
338             }
339              
340             sub _getter {
341 0     0     my ($self, $attrib, $where, %guard);
342              
343 0 0         if (@_ % 2 == 0) {
344 0           ($self, $attrib, %guard) = @_;
345             }
346             else {
347 0           ($self, $attrib, $where) = @_;
348             }
349              
350 0           my @ret = ();
351              
352 0           for (@{ $self->$attrib }) {
  0            
353 0 0         if (ref $where eq 'CODE') {
354 0 0         push(@ret,$_) if $where->($_);
355             }
356             else {
357 0           my $ok = 1;
358 0           for my $k (keys %guard) {
359 0           my $val = $guard{$k};
360 0 0 0       $ok = 0 unless (defined $_->$k && $_->$k eq $val);
361             }
362 0 0         push(@ret,$_) if $ok == 1;
363             }
364             }
365              
366 0 0         wantarray ? @ret : $ret[0];
367             }
368              
369             sub _setter {
370 0     0     my ($self, $attrib, @objs) = @_;
371 0           my $ret;
372              
373 0 0 0       if (@objs == 0) {
    0 0        
    0          
374 0           $ret = $self->$attrib;
375             }
376             elsif (@objs == 1 && ref($objs[0]) eq 'ARRAY') {
377 0           $self->$attrib($objs[0]);
378 0           $ret = $objs[0];
379             }
380             elsif (@objs == 1 && !defined $objs[0]) {
381 0           $self->$attrib([]);
382 0           $ret = [];
383             }
384             else {
385 0           $self->$attrib(\@objs);
386 0           $ret = \@objs;
387             }
388              
389 0 0         wantarray ? @$ret : $ret;
390             }
391              
392             sub _adder {
393 0     0     my ($self, $attrib, $obj,%opts);
394              
395 0 0         if (@_ % 2 == 0) {
396 0           ($self, $attrib,%opts) = @_;
397             }
398             else {
399 0           ($self, $attrib, $obj,%opts) = @_;
400             }
401              
402 0           my $class = $attrib;
403 0           $class =~ s{^(.)}{uc($1)}e;
  0            
404 0           $class = "MODS::Element::$class";
405              
406 0 0 0       if (ref $obj eq 'CODE') {
    0          
    0          
    0          
407 0           my $sub = $obj;
408 0           $obj = $class->new(%opts);
409 0           my $ref = $self->$attrib;
410 0           push (@$ref,$obj);
411 0           $self->$attrib($ref);
412 0           $sub->($obj);
413             }
414             elsif (ref $obj eq $class) {
415 0           my $ref = $self->$attrib;
416 0           push (@$ref,$obj);
417 0           $self->$attrib($ref);
418             }
419             elsif (defined $obj && $class->can('_body')) {
420 0           $obj = $class->new(_body => $obj, %opts);
421 0           my $ref = $self->$attrib;
422 0           push (@$ref,$obj);
423 0           $self->$attrib($ref);
424             }
425             elsif (! defined $obj) {
426 0           $obj = $class->new(%opts);
427 0           my $ref = $self->$attrib;
428 0           push (@$ref,$obj);
429 0           $self->$attrib($ref);
430             }
431             else {
432 0           croak "eek: self($self) class($class) obj($obj)";
433             }
434              
435 0 0         if ($obj->does('MODS::Record::Unique')) {
436 0           my $ref = $self->$attrib;
437 0           $self->$attrib([$ref->[-1]]);
438             }
439              
440 0           $obj;
441             }
442              
443             sub _isa {
444 0     0     my $type = shift;
445              
446 0 0         die "Need an array of MODS::Element::*" unless ref $type eq 'ARRAY';
447              
448 0           for (@$type) {
449 0 0         die "Need a element of MODS::Element::*" unless ref($_) =~ /^MODS::Element::/;
450             }
451             }
452              
453             sub body {
454 0     0 0   my ($self,$val) = @_;
455              
456 0 0         if ($self->can('_body')) {
457 0 0         $self->_body($val) if defined $val;
458 0           return $self->_body;
459             }
460             else {
461 0           return undef;
462             }
463             }
464              
465             sub as_xml {
466 0     0 0   my ($self,%opts) = @_;
467              
468 0           my $output = '';
469 0           my $class = ref $self;
470 0           $class =~ s{^(.*)::(.)(.*)}{lc($2) . $3}e;
  0            
471              
472 0   0       my $encoding = $opts{'encoding'} || 'UTF-8';
473              
474 0 0         $output .= "\n" if $opts{'xml_prolog'};
475              
476 0           $output .= "
477              
478 0 0 0       if ($class eq 'mods' || $class eq 'modsCollection' ) {
479 0           $output .= ' xmlns:mods="http://www.loc.gov/mods/v3"';
480 0           $output .= ' xmlns:xlink="http://www.w3.org/1999/xlink"';
481 0           $output .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
482 0           $output .= ' xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-5.xsd"';
483             }
484              
485 0           for my $key (keys %$self) {
486 0           my $val = $self->$key;
487 0 0         if ($key =~ /^_/) {
    0          
488 0           next;
489             }
490             elsif (ref $val eq '') {
491 0           $output .= " $key=\"" . escape($val) . "\"";
492             }
493             }
494              
495 0           $output .= ">";
496              
497 0 0         if ($self->can('_body')) {
498 0 0 0       if (ref $self->_body && $self->_body->can('as_xml')) {
499 0           $output .= $self->_body->as_xml;
500             }
501             else {
502 0           $output .= escape($self->_body);
503             }
504             }
505              
506 0           for my $key (keys %$self) {
507 0           my $val = $self->$key;
508            
509 0 0 0       if ($key =~ /^_/ || ref $val ne 'ARRAY') {
510 0           next;
511             }
512              
513 0           for (@{ $self->$key} ) {
  0            
514 0           $output .= $_->as_xml;
515             }
516             }
517              
518 0           $output .= "";
519 0           $output;
520             }
521              
522             sub as_json {
523 0     0 0   my ($self, %opts) = @_;
524 0           my $class = ref $self;
525 0           $class =~ s{^(.*)::(.)(.*)}{lc($2) . $3}e;
  0            
526 0           to_json({$class => $self}, { utf8 => 1, convert_blessed => 1 , allow_blessed => 1 , pretty => $opts{pretty}});
527             }
528              
529             sub TO_JSON {
530 0     0 0   my $ret = { %{ shift() } };
  0            
531 0           for (keys %$ret) {
532 0 0 0       if (ref $ret->{$_} eq 'ARRAY' && @{$ret->{$_}} == 0) {
  0            
533 0           delete $ret->{$_};
534             }
535             }
536 0           $ret;
537             }
538              
539             package MODS::Record::Unique;
540              
541 2     2   4004 use Moo::Role;
  2         4  
  2         19  
542              
543             package MODS::Record::Xml_String;
544              
545 2     2   5392 use Moo;
  2         4665  
  2         13  
546              
547 2     2   4185 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         21  
  0         0  
548              
549             has _body => (is => 'ro');
550              
551             sub as_xml {
552 0     0 0   my $self = shift;
553 0           $self->_body;
554             }
555              
556 0     0 0   sub TO_JSON { return shift->_body; }
557              
558             package MODS::Element::Abstract;
559              
560 2     2   273 use Moo;
  2         3  
  2         11  
561              
562             with('MODS::Record::Util');
563              
564 2     2   647 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         12  
  0         0  
565              
566             has lang => ( is => 'rw' );
567             has xml_lang => ( is => 'rw' );
568             has script => ( is => 'rw' );
569             has transliteration => ( is => 'rw' );
570              
571             has displayLabel => ( is => 'rw' );
572             has type => ( is => 'rw' );
573             has xlink => ( is => 'rw' );
574             has shareable => ( is => 'rw' );
575             has altRepGroup => ( is => 'rw' );
576             has altFormat => ( is => 'rw' );
577             has contentType => ( is => 'rw' );
578             has _body => ( is => 'rw' );
579              
580             package MODS::Element::AccessCondition;
581              
582 2     2   329 use Moo;
  2         5  
  2         7  
583              
584             with('MODS::Record::Util');
585              
586 2     2   578 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         11  
  0         0  
587              
588             has lang => ( is => 'rw' );
589             has xml_lang => ( is => 'rw' );
590             has script => ( is => 'rw' );
591             has transliteration => ( is => 'rw' );
592              
593             has xlink => ( is => 'rw' );
594              
595             has type => ( is => 'rw' );
596             has altRepGroup => ( is => 'rw' );
597             has altFormat => ( is => 'rw' );
598             has contentType => ( is => 'rw' );
599             has _body => ( is => 'rw' );
600              
601             package MODS::Element::Affiliation;
602              
603 2     2   333 use Moo;
  2         4  
  2         8  
604              
605             with('MODS::Record::Util','MODS::Record::Unique');
606              
607             package MODS::Element::Classification;
608              
609 2     2   552 use Moo;
  2         5  
  2         9  
610              
611             with('MODS::Record::Util');
612              
613 2     2   584 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         11  
  0         0  
614              
615             has lang => ( is => 'rw' );
616             has xml_lang => ( is => 'rw' );
617             has script => ( is => 'rw' );
618             has transliteration => ( is => 'rw' );
619              
620             has authorityURI => ( is => 'rw' );
621             has valueURI => ( is => 'rw' );
622             has authority => ( is => 'rw' );
623              
624             has edition => ( is => 'rw' );
625             has displayLabel => ( is => 'rw' );
626             has altRepGroup => ( is => 'rw' );
627             has usage => ( is => 'rw' );
628             has generator => ( is => 'rw' );
629             has _body => ( is => 'rw' );
630              
631             package MODS::Element::Extension;
632              
633 2     2   361 use Moo;
  2         3  
  2         7  
634              
635             with('MODS::Record::Util');
636              
637             has displayLabel => ( is => 'rw' );
638             has _body => ( is => 'rw' );
639              
640 2     2   636 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         13  
  0         0  
641              
642             package MODS::Element::Genre;
643              
644             # [Warning]
645             # The genre-element in MODS is used in different context.
646             # All solution we provide here the broadest possible interpretation.
647 2     2   151 use Moo;
  2         3  
  2         7  
648              
649             with('MODS::Record::Util');
650              
651 2     2   581 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         11  
  0         0  
652              
653             has lang => ( is => 'rw' );
654             has xml_lang => ( is => 'rw' );
655             has script => ( is => 'rw' );
656             has transliteration => ( is => 'rw' );
657              
658             has authorityURI => ( is => 'rw' );
659             has valueURI => ( is => 'rw' );
660             has authority => ( is => 'rw' );
661              
662             has displayLabel => ( is => 'rw' );
663             has altRepGroup => ( is => 'rw' );
664             has usage => ( is => 'rw' );
665             has _body => ( is => 'rw' );
666              
667             package MODS::Element::Identifier;
668              
669 2     2   280 use Moo;
  2         3  
  2         8  
670              
671             with('MODS::Record::Util');
672              
673 2     2   599 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         11  
  0         0  
674              
675             has lang => ( is => 'rw' );
676             has xml_lang => ( is => 'rw' );
677             has script => ( is => 'rw' );
678             has transliteration => ( is => 'rw' );
679              
680             has displayLabel => ( is => 'rw' );
681             has type => ( is => 'rw' );
682             has typeURI => ( is => 'rw' );
683             has invalid => ( is => 'rw' );
684             has _body => ( is => 'rw' );
685              
686             package MODS::Element::Language;
687              
688 2     2   415 use Moo;
  2         4  
  2         13  
689              
690             with('MODS::Record::Util');
691              
692             has objectPart => ( is => 'rw' );
693              
694             has lang => ( is => 'rw' );
695             has xml_lang => ( is => 'rw' );
696             has script => ( is => 'rw' );
697             has transliteration => ( is => 'rw' );
698              
699             has displayLabel => ( is => 'rw' );
700             has altRepGroup => ( is => 'rw' );
701             has usage => ( is => 'rw' );
702             has languageTerm => ( is => 'rw' , isa => \&_isa , default => sub { [] });
703             has scriptTerm => ( is => 'rw' , isa => \&_isa , default => sub { [] });
704              
705             package MODS::Element::LanguageTerm;
706              
707 2     2   835 use Moo;
  2         3  
  2         15  
708              
709             with('MODS::Record::Util');
710              
711 2     2   613 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         20  
  0         0  
712              
713             has lang => ( is => 'rw' );
714             has xml_lang => ( is => 'rw' );
715             has script => ( is => 'rw' );
716             has transliteration => ( is => 'rw' );
717              
718             has authorityURI => ( is => 'rw' );
719             has valueURI => ( is => 'rw' );
720             has authority => ( is => 'rw' );
721             has type => ( is => 'rw' );
722             has _body => ( is => 'rw' );
723              
724             package MODS::Element::ScriptTerm;
725              
726 2     2   338 use Moo;
  2         4  
  2         10  
727              
728             with('MODS::Record::Util');
729              
730 2     2   581 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         13  
  0         0  
731              
732             has lang => ( is => 'rw' );
733             has xml_lang => ( is => 'rw' );
734             has script => ( is => 'rw' );
735             has transliteration => ( is => 'rw' );
736              
737             has authorityURI => ( is => 'rw' );
738             has valueURI => ( is => 'rw' );
739             has authority => ( is => 'rw' );
740              
741             has type => ( is => 'rw' );
742             has _body => ( is => 'rw' );
743              
744             package MODS::Element::Location;
745              
746 2     2   272 use Moo;
  2         4  
  2         19  
747              
748             with('MODS::Record::Util');
749              
750             has lang => ( is => 'rw' );
751             has xml_lang => ( is => 'rw' );
752             has script => ( is => 'rw' );
753             has transliteration => ( is => 'rw' );
754              
755             has displayLabel => ( is => 'rw' );
756             has altRepGroup => ( is => 'rw' );
757             has physicalLocation => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
758             has shelfLocator => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
759             has url => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
760             has holdingSimple => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
761             has holdingExternal => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
762              
763             package MODS::Element::PhysicalLocation;
764              
765 2     2   867 use Moo;
  2         3  
  2         12  
766              
767             with('MODS::Record::Util');
768              
769 2     2   577 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   8  
  2         12  
  0         0  
770              
771             has lang => ( is => 'rw' );
772             has xml_lang => ( is => 'rw' );
773             has script => ( is => 'rw' );
774             has transliteration => ( is => 'rw' );
775              
776             has authorityURI => ( is => 'rw' );
777             has valueURI => ( is => 'rw' );
778             has authority => ( is => 'rw' );
779              
780             has displayLabel => ( is => 'rw' );
781             has type => ( is => 'rw' );
782             has xlink => ( is => 'rw' );
783             has _body => ( is => 'rw' );
784              
785             package MODS::Element::Url;
786              
787 2     2   292 use Moo;
  2         15  
  2         9  
788              
789             with('MODS::Record::Util');
790              
791 2     2   664 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         12  
  0         0  
792              
793             has dateLastAccessed => ( is => 'rw' );
794             has displayLabel => ( is => 'rw' );
795             has note => ( is => 'rw' );
796             has access => ( is => 'rw' );
797             has usage => ( is => 'rw' );
798             has _body => ( is => 'rw' );
799              
800             package MODS::Element::HoldingSimple;
801              
802 2     2   226 use Moo;
  2         4  
  2         7  
803              
804             with('MODS::Record::Util','MODS::Record::Unique');
805              
806             has copyInformation => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
807              
808             package MODS::Element::CopyInformation;
809              
810 2     2   591 use Moo;
  2         3  
  2         8  
811              
812             with('MODS::Record::Util');
813              
814             has form => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
815             has subLocation => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
816             has shelfLocator => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
817             has electronicLocator => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
818             has note => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
819             has enumerationAndChronology => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
820              
821             package MODS::Element::Form;
822              
823 2     2   873 use Moo;
  2         20  
  2         8  
824              
825             # [Warning]
826             # The form-element is used in more than one context in MODS. One usage
827             # required unique, the other usag is repeatable. We use the latter here
828             # for all 'form'-elements.
829             with('MODS::Record::Util');
830              
831 2     2   696 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
832              
833             has lang => ( is => 'rw' );
834             has xml_lang => ( is => 'rw' );
835             has script => ( is => 'rw' );
836             has transliteration => ( is => 'rw' );
837              
838             has authorityURI => ( is => 'rw' );
839             has valueURI => ( is => 'rw' );
840             has authority => ( is => 'rw' );
841              
842             has type => ( is => 'rw' );
843             has ID => ( is => 'rw' );
844             has _body => ( is => 'rw' );
845              
846             package MODS::Element::SubLocation;
847              
848 2     2   250 use Moo;
  2         3  
  2         7  
849              
850             with('MODS::Record::Util');
851              
852 2     2   525 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         13  
  0         0  
853              
854             has lang => ( is => 'rw' );
855             has xml_lang => ( is => 'rw' );
856             has script => ( is => 'rw' );
857             has transliteration => ( is => 'rw' );
858              
859             has _body => ( is => 'rw' );
860              
861             package MODS::Element::ShelfLocator;
862              
863 2     2   179 use Moo;
  2         6  
  2         7  
864              
865             with('MODS::Record::Util');
866              
867 2     2   492 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
868              
869             has lang => ( is => 'rw' );
870             has xml_lang => ( is => 'rw' );
871             has script => ( is => 'rw' );
872             has transliteration => ( is => 'rw' );
873              
874             has _body => ( is => 'rw' );
875              
876             package MODS::Element::Note;
877              
878 2     2   278 use Moo;
  2         2  
  2         11  
879              
880             with('MODS::Record::Util');
881              
882 2     2   545 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         10  
  0         0  
883              
884             has lang => ( is => 'rw' );
885             has xml_lang => ( is => 'rw' );
886             has script => ( is => 'rw' );
887             has transliteration => ( is => 'rw' );
888              
889             has ID => ( is => 'rw' );
890             has displayLabel => ( is => 'rw' );
891             has type => ( is => 'rw' );
892             has typeURI => ( is => 'rw' );
893             has altRepGroup => ( is => 'rw' );
894             has xlink => ( is => 'rw' );
895              
896             has _body => ( is => 'rw' );
897              
898             package MODS::Element::EnumerationAndChronology;
899              
900 2     2   263 use Moo;
  2         3  
  2         6  
901              
902             with('MODS::Record::Util');
903              
904 2     2   501 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   15  
  2         16  
  0         0  
905              
906             has lang => ( is => 'rw' );
907             has xml_lang => ( is => 'rw' );
908             has script => ( is => 'rw' );
909             has transliteration => ( is => 'rw' );
910              
911             has unitType => ( is => 'rw' );
912             has _body => ( is => 'rw' );
913              
914             package MODS::Element::HoldingExternal;
915              
916 2     2   195 use Moo;
  2         3  
  2         7  
917              
918             with('MODS::Record::Util','MODS::Record::Unique');
919              
920 2     2   510 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         18  
  0         0  
921              
922             has displayLabel => ( is => 'rw' );
923             has _body => ( is => 'rw' );
924              
925              
926             package MODS::Element::Name;
927              
928 2     2   190 use Moo;
  2         8  
  2         6  
929              
930             with('MODS::Record::Util');
931              
932             has lang => ( is => 'rw' );
933             has xml_lang => ( is => 'rw' );
934             has script => ( is => 'rw' );
935             has transliteration => ( is => 'rw' );
936              
937             has authorityURI => ( is => 'rw' );
938             has valueURI => ( is => 'rw' );
939             has authority => ( is => 'rw' );
940              
941             has ID => ( is => 'rw' );
942             has xlink => ( is => 'rw' );
943             has displayLabel => ( is => 'rw' );
944             has usage => ( is => 'rw' );
945             has altRepGroup => ( is => 'rw' );
946             has nameTitleGroup => ( is => 'rw' );
947              
948             has namePart => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
949             has displayForm => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
950             has affiliation => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
951             has role => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
952             has description => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
953             has etal => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
954              
955             package MODS::Element::NamePart;
956              
957 2     2   908 use Moo;
  2         3  
  2         7  
958              
959             with('MODS::Record::Util');
960              
961 2     2   494 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         20  
  0         0  
962              
963             has lang => ( is => 'rw' );
964             has xml_lang => ( is => 'rw' );
965             has script => ( is => 'rw' );
966             has transliteration => ( is => 'rw' );
967              
968             has type => ( is => 'rw' );
969             has _body => ( is => 'rw' );
970              
971             package MODS::Element::DisplayForm;
972              
973 2     2   251 use Moo;
  2         2  
  2         7  
974              
975             with('MODS::Record::Util');
976              
977 2     2   485 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         14  
  0         0  
978              
979             has lang => ( is => 'rw' );
980             has xml_lang => ( is => 'rw' );
981             has script => ( is => 'rw' );
982             has transliteration => ( is => 'rw' );
983              
984             has _body => ( is => 'rw' );
985              
986             package MODS::Element::Role;
987              
988 2     2   185 use Moo;
  2         3  
  2         7  
989              
990             with('MODS::Record::Util');
991              
992             has roleTerm => ( is => 'rw' , default => sub{ [] } );
993              
994              
995             package MODS::Element::RoleTerm;
996              
997 2     2   525 use Moo;
  2         8  
  2         11  
998              
999             with('MODS::Record::Util');
1000              
1001 2     2   532 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1002              
1003             has lang => ( is => 'rw' );
1004             has xml_lang => ( is => 'rw' );
1005             has script => ( is => 'rw' );
1006             has transliteration => ( is => 'rw' );
1007              
1008             has authorityURI => ( is => 'rw' );
1009             has valueURI => ( is => 'rw' );
1010             has authority => ( is => 'rw' );
1011              
1012             has type => ( is => 'rw' );
1013             has _body => ( is => 'rw' );
1014              
1015             package MODS::Element::Description;
1016              
1017 2     2   271 use Moo;
  2         4  
  2         7  
1018              
1019             with('MODS::Record::Util');
1020              
1021 2     2   511 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         13  
  0         0  
1022              
1023             has lang => ( is => 'rw' );
1024             has xml_lang => ( is => 'rw' );
1025             has script => ( is => 'rw' );
1026             has transliteration => ( is => 'rw' );
1027              
1028             has _body => ( is => 'rw' );
1029              
1030             package MODS::Element::Etal;
1031              
1032 2     2   188 use Moo;
  2         4  
  2         11  
1033              
1034             with('MODS::Record::Util','MODS::Record::Unique');
1035              
1036             package MODS::Element::OriginInfo;
1037              
1038 2     2   461 use Moo;
  2         3  
  2         11  
1039              
1040             with('MODS::Record::Util');
1041              
1042             has lang => ( is => 'rw' );
1043             has xml_lang => ( is => 'rw' );
1044             has script => ( is => 'rw' );
1045             has transliteration => ( is => 'rw' );
1046              
1047             has displayLabel => ( is => 'rw' );
1048             has altRepGroup => ( is => 'rw' );
1049             has eventType => ( is => 'rw' );
1050              
1051             has place => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1052             has publisher => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1053             has dateIssued => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1054             has dateCreated => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1055             has dateCaptured => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1056             has dateValid => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1057             has dateModified => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1058             has copyrightDate => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1059             has dateOther => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1060             has edition => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1061             has issuance => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1062             has frequency => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1063              
1064             package MODS::Element::Place;
1065              
1066 2     2   1225 use Moo;
  2         4  
  2         6  
1067              
1068             with('MODS::Record::Util');
1069              
1070             has supplied => ( is => 'rw' );
1071             has placeTerm => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1072              
1073             package MODS::Element::PlaceTerm;
1074              
1075 2     2   548 use Moo;
  2         4  
  2         6  
1076              
1077             with('MODS::Record::Util');
1078              
1079 2     2   545 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
1080              
1081             has lang => ( is => 'rw' );
1082             has xml_lang => ( is => 'rw' );
1083             has script => ( is => 'rw' );
1084             has transliteration => ( is => 'rw' );
1085              
1086             has authorityURI => ( is => 'rw' );
1087             has valueURI => ( is => 'rw' );
1088             has authority => ( is => 'rw' );
1089              
1090             has type => ( is => 'rw' );
1091             has _body => ( is => 'rw' );
1092              
1093             package MODS::Element::Publisher;
1094              
1095 2     2   341 use Moo;
  2         5  
  2         7  
1096              
1097             with('MODS::Record::Util');
1098              
1099 2     2   512 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         9  
  0         0  
1100              
1101             has lang => ( is => 'rw' );
1102             has xml_lang => ( is => 'rw' );
1103             has script => ( is => 'rw' );
1104             has transliteration => ( is => 'rw' );
1105              
1106             has supplied => ( is => 'rw' );
1107             has _body => ( is => 'rw' );
1108              
1109             package MODS::Element::DateIssued;
1110              
1111 2     2   245 use Moo;
  2         3  
  2         7  
1112              
1113             with('MODS::Record::Util');
1114              
1115 2     2   549 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         20  
  0         0  
1116              
1117             has lang => ( is => 'rw' );
1118             has xml_lang => ( is => 'rw' );
1119             has script => ( is => 'rw' );
1120             has transliteration => ( is => 'rw' );
1121              
1122             has encoding => ( is => 'rw' );
1123             has point => ( is => 'rw' );
1124             has keyDate => ( is => 'rw' );
1125             has qualifier => ( is => 'rw' );
1126             has _body => ( is => 'rw' );
1127              
1128             package MODS::Element::DateCreated;
1129              
1130 2     2   277 use Moo;
  2         4  
  2         13  
1131              
1132             with('MODS::Record::Util');
1133              
1134 2     2   504 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         15  
  0         0  
1135              
1136             has lang => ( is => 'rw' );
1137             has xml_lang => ( is => 'rw' );
1138             has script => ( is => 'rw' );
1139             has transliteration => ( is => 'rw' );
1140              
1141             has encoding => ( is => 'rw' );
1142             has point => ( is => 'rw' );
1143             has keyDate => ( is => 'rw' );
1144             has qualifier => ( is => 'rw' );
1145             has _body => ( is => 'rw' );
1146              
1147             package MODS::Element::DateCaptured;
1148              
1149 2     2   238 use Moo;
  2         2  
  2         7  
1150              
1151             with('MODS::Record::Util');
1152              
1153 2     2   497 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         11  
  0         0  
1154              
1155             has lang => ( is => 'rw' );
1156             has xml_lang => ( is => 'rw' );
1157             has script => ( is => 'rw' );
1158             has transliteration => ( is => 'rw' );
1159              
1160             has encoding => ( is => 'rw' );
1161             has point => ( is => 'rw' );
1162             has keyDate => ( is => 'rw' );
1163             has qualifier => ( is => 'rw' );
1164             has _body => ( is => 'rw' );
1165              
1166             package MODS::Element::DateValid;
1167              
1168 2     2   279 use Moo;
  2         3  
  2         8  
1169              
1170             with('MODS::Record::Util');
1171              
1172 2     2   520 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         16  
  0         0  
1173              
1174             has lang => ( is => 'rw' );
1175             has xml_lang => ( is => 'rw' );
1176             has script => ( is => 'rw' );
1177             has transliteration => ( is => 'rw' );
1178              
1179             has encoding => ( is => 'rw' );
1180             has point => ( is => 'rw' );
1181             has keyDate => ( is => 'rw' );
1182             has qualifier => ( is => 'rw' );
1183             has _body => ( is => 'rw' );
1184              
1185             package MODS::Element::DateModified;
1186              
1187 2     2   290 use Moo;
  2         3  
  2         7  
1188              
1189             with('MODS::Record::Util');
1190              
1191 2     2   571 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         11  
  0         0  
1192              
1193             has lang => ( is => 'rw' );
1194             has xml_lang => ( is => 'rw' );
1195             has script => ( is => 'rw' );
1196             has transliteration => ( is => 'rw' );
1197              
1198             has encoding => ( is => 'rw' );
1199             has point => ( is => 'rw' );
1200             has keyDate => ( is => 'rw' );
1201             has qualifier => ( is => 'rw' );
1202             has _body => ( is => 'rw' );
1203              
1204             package MODS::Element::CopyrightDate;
1205              
1206 2     2   314 use Moo;
  2         4  
  2         11  
1207              
1208             with('MODS::Record::Util');
1209              
1210 2     2   487 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         15  
  0         0  
1211              
1212             has lang => ( is => 'rw' );
1213             has xml_lang => ( is => 'rw' );
1214             has script => ( is => 'rw' );
1215             has transliteration => ( is => 'rw' );
1216              
1217             has encoding => ( is => 'rw' );
1218             has point => ( is => 'rw' );
1219             has keyDate => ( is => 'rw' );
1220             has qualifier => ( is => 'rw' );
1221             has _body => ( is => 'rw' );
1222              
1223             package MODS::Element::DateOther;
1224              
1225 2     2   239 use Moo;
  2         3  
  2         12  
1226              
1227             with('MODS::Record::Util');
1228              
1229 2     2   519 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         15  
  0         0  
1230              
1231             has lang => ( is => 'rw' );
1232             has xml_lang => ( is => 'rw' );
1233             has script => ( is => 'rw' );
1234             has transliteration => ( is => 'rw' );
1235              
1236             has encoding => ( is => 'rw' );
1237             has point => ( is => 'rw' );
1238             has keyDate => ( is => 'rw' );
1239             has qualifier => ( is => 'rw' );
1240             has _body => ( is => 'rw' );
1241              
1242             package MODS::Element::Edition;
1243              
1244 2     2   302 use Moo;
  2         3  
  2         13  
1245              
1246             with('MODS::Record::Util');
1247              
1248 2     2   524 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1249              
1250             has lang => ( is => 'rw' );
1251             has xml_lang => ( is => 'rw' );
1252             has script => ( is => 'rw' );
1253             has transliteration => ( is => 'rw' );
1254              
1255             has supplied => ( is => 'rw' );
1256             has _body => ( is => 'rw' );
1257              
1258             package MODS::Element::Issuance;
1259              
1260 2     2   205 use Moo;
  2         4  
  2         11  
1261              
1262             with('MODS::Record::Util');
1263              
1264 2     2   488 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         9  
  0         0  
1265              
1266             has _body => ( is => 'rw' );
1267              
1268             package MODS::Element::Frequency;
1269              
1270 2     2   133 use Moo;
  2         3  
  2         12  
1271              
1272             with('MODS::Record::Util');
1273              
1274 2     2   540 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         16  
  0         0  
1275              
1276             has lang => ( is => 'rw' );
1277             has xml_lang => ( is => 'rw' );
1278             has script => ( is => 'rw' );
1279             has transliteration => ( is => 'rw' );
1280              
1281             has authorityURI => ( is => 'rw' );
1282             has valueURI => ( is => 'rw' );
1283             has authority => ( is => 'rw' );
1284              
1285             has _body => ( is => 'rw' );
1286              
1287             package MODS::Element::Part;
1288              
1289 2     2   237 use Moo;
  2         2  
  2         8  
1290              
1291             with('MODS::Record::Util');
1292              
1293             has lang => ( is => 'rw' );
1294             has xml_lang => ( is => 'rw' );
1295             has script => ( is => 'rw' );
1296             has transliteration => ( is => 'rw' );
1297              
1298             has ID => ( is => 'rw' );
1299             has type => ( is => 'rw' );
1300             has order => ( is => 'rw' );
1301             has displayLabel => ( is => 'rw' );
1302             has altRepGroup => ( is => 'rw' );
1303              
1304             has detail => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1305             has extent => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1306             has date => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1307             has text => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1308              
1309             package MODS::Element::Detail;
1310              
1311 2     2   858 use Moo;
  2         2  
  2         7  
1312              
1313             with('MODS::Record::Util');
1314              
1315             has type => ( is => 'rw' );
1316             has level => ( is => 'rw' );
1317              
1318             has number => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1319             has caption => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1320             has title => ( is => 'rw' , isa => \&_isa , default => sub { [] } );
1321              
1322             package MODS::Element::Number;
1323              
1324 2     2   677 use Moo;
  2         3  
  2         7  
1325              
1326             with('MODS::Record::Util');
1327              
1328 2     2   495 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1329              
1330             has lang => ( is => 'rw' );
1331             has xml_lang => ( is => 'rw' );
1332             has script => ( is => 'rw' );
1333             has transliteration => ( is => 'rw' );
1334              
1335             has _body => ( is => 'rw' );
1336              
1337             package MODS::Element::Caption;
1338              
1339 2     2   180 use Moo;
  2         3  
  2         6  
1340              
1341             with('MODS::Record::Util');
1342              
1343 2     2   542 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   12  
  2         11  
  0         0  
1344              
1345             has lang => ( is => 'rw' );
1346             has xml_lang => ( is => 'rw' );
1347             has script => ( is => 'rw' );
1348             has transliteration => ( is => 'rw' );
1349              
1350             has _body => ( is => 'rw' );
1351              
1352             package MODS::Element::Extent;
1353              
1354 2     2   230 use Moo;
  2         2  
  2         7  
1355              
1356             with('MODS::Record::Util');
1357              
1358 2     2   483 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   9  
  2         14  
  0         0  
1359              
1360             # [Warning]
1361             # The 'extent' element is used in MODS in two different contexts.
1362             # As temporary solution we push all possible attributes in one Extent-package...
1363              
1364             has lang => ( is => 'rw' );
1365             has xml_lang => ( is => 'rw' );
1366             has script => ( is => 'rw' );
1367             has transliteration => ( is => 'rw' );
1368              
1369             has supplied => ( is => 'rw' );
1370             has unit => ( is => 'rw' );
1371              
1372             has start => ( is => 'rw' , default => sub {[]});
1373             has end => ( is => 'rw' , default => sub {[]});
1374             has total => ( is => 'rw' , default => sub {[]});
1375             has list => ( is => 'rw' , default => sub {[]});
1376              
1377             has _body => ( is => 'rw' );
1378              
1379             package MODS::Element::Start;
1380              
1381 2     2   385 use Moo;
  2         3  
  2         7  
1382              
1383             with('MODS::Record::Util');
1384              
1385 2     2   577 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         12  
  0         0  
1386              
1387             has lang => ( is => 'rw' );
1388             has xml_lang => ( is => 'rw' );
1389             has script => ( is => 'rw' );
1390             has transliteration => ( is => 'rw' );
1391              
1392             has _body => ( is => 'rw' );
1393              
1394             package MODS::Element::End;
1395              
1396 2     2   187 use Moo;
  2         3  
  2         7  
1397              
1398             with('MODS::Record::Util');
1399              
1400 2     2   507 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         16  
  0         0  
1401              
1402             has lang => ( is => 'rw' );
1403             has xml_lang => ( is => 'rw' );
1404             has script => ( is => 'rw' );
1405             has transliteration => ( is => 'rw' );
1406              
1407             has _body => ( is => 'rw' );
1408              
1409             package MODS::Element::Total;
1410              
1411 2     2   234 use Moo;
  2         3  
  2         7  
1412              
1413             with('MODS::Record::Util');
1414              
1415 2     2   581 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
1416              
1417             has _body => ( is => 'rw' );
1418              
1419             package MODS::Element::List;
1420              
1421 2     2   134 use Moo;
  2         2  
  2         13  
1422              
1423             with('MODS::Record::Util');
1424              
1425 2     2   490 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   7  
  2         16  
  0         0  
1426              
1427             has lang => ( is => 'rw' );
1428             has xml_lang => ( is => 'rw' );
1429             has script => ( is => 'rw' );
1430             has transliteration => ( is => 'rw' );
1431              
1432             has _body => ( is => 'rw' );
1433              
1434             package MODS::Element::Date;
1435              
1436 2     2   230 use Moo;
  2         2  
  2         8  
1437              
1438             with('MODS::Record::Util');
1439              
1440 2     2   507 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1441              
1442             has lang => ( is => 'rw' );
1443             has xml_lang => ( is => 'rw' );
1444             has script => ( is => 'rw' );
1445             has transliteration => ( is => 'rw' );
1446              
1447             has encoding => ( is => 'rw' );
1448             has point => ( is => 'rw' );
1449             has qualifier => ( is => 'rw' );
1450             has _body => ( is => 'rw' );
1451              
1452             package MODS::Element::Text;
1453              
1454 2     2   214 use Moo;
  2         3  
  2         15  
1455              
1456             with('MODS::Record::Util');
1457              
1458 2     2   496 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1459              
1460             has lang => ( is => 'rw' );
1461             has xml_lang => ( is => 'rw' );
1462             has script => ( is => 'rw' );
1463             has transliteration => ( is => 'rw' );
1464              
1465             has displayLabel => ( is => 'rw' );
1466             has xlink => ( is => 'rw' );
1467             has type => ( is => 'rw' );
1468             has _body => ( is => 'rw' );
1469              
1470             package MODS::Element::PhysicalDescription;
1471              
1472 2     2   322 use Moo;
  2         5  
  2         12  
1473              
1474             with('MODS::Record::Util');
1475              
1476             has lang => ( is => 'rw' );
1477             has xml_lang => ( is => 'rw' );
1478             has script => ( is => 'rw' );
1479             has transliteration => ( is => 'rw' );
1480              
1481             has displayLabel => ( is => 'rw' );
1482             has altRepGroup => ( is => 'rw' );
1483             has form => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1484             has reformattingQuality => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1485             has internetMediaType => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1486             has extent => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1487             has digitalOrigin => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1488             has note => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1489              
1490             package MODS::Element::ReformattingQuality;
1491              
1492 2     2   888 use Moo;
  2         3  
  2         7  
1493              
1494             with('MODS::Record::Util');
1495              
1496 2     2   521 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1497              
1498             has _body => ( is => 'rw' );
1499              
1500             package MODS::Element::InternetMediaType;
1501              
1502 2     2   137 use Moo;
  2         3  
  2         33  
1503              
1504             with('MODS::Record::Util');
1505              
1506 2     2   591 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         14  
  0         0  
1507              
1508             has lang => ( is => 'rw' );
1509             has xml_lang => ( is => 'rw' );
1510             has script => ( is => 'rw' );
1511             has transliteration => ( is => 'rw' );
1512              
1513             has _body => ( is => 'rw' );
1514              
1515             package MODS::Element::DigitalOrigin;
1516              
1517 2     2   202 use Moo;
  2         3  
  2         7  
1518              
1519             with('MODS::Record::Util');
1520              
1521 2     2   498 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         15  
  0         0  
1522              
1523             has _body => ( is => 'rw' );
1524              
1525             package MODS::Element::RecordInfo;
1526              
1527 2     2   135 use Moo;
  2         2  
  2         8  
1528              
1529             with('MODS::Record::Util');
1530              
1531             has lang => ( is => 'rw' );
1532             has xml_lang => ( is => 'rw' );
1533             has script => ( is => 'rw' );
1534             has transliteration => ( is => 'rw' );
1535              
1536             has displayLabel => ( is => 'rw' );
1537             has altRepGroup => ( is => 'rw' );
1538              
1539             has recordContentSource => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1540             has recordCreationDate => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1541             has recordChangeDate => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1542             has recordIdentifier => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1543             has recordOrigin => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1544             has languageOfCataloging => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1545             has descriptionStandard => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1546              
1547             package MODS::Element::RecordContentSource;
1548              
1549 2     2   924 use Moo;
  2         8  
  2         12  
1550              
1551             with('MODS::Record::Util');
1552              
1553 2     2   508 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   10  
  2         11  
  0         0  
1554              
1555             has lang => ( is => 'rw' );
1556             has xml_lang => ( is => 'rw' );
1557             has script => ( is => 'rw' );
1558             has transliteration => ( is => 'rw' );
1559              
1560             has authorityURI => ( is => 'rw' );
1561             has valueURI => ( is => 'rw' );
1562             has authority => ( is => 'rw' );
1563              
1564             has _body => ( is => 'rw' );
1565              
1566             package MODS::Element::RecordCreationDate;
1567              
1568 2     2   224 use Moo;
  2         5  
  2         7  
1569              
1570             with('MODS::Record::Util');
1571              
1572 2     2   532 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1573              
1574             has lang => ( is => 'rw' );
1575             has xml_lang => ( is => 'rw' );
1576             has script => ( is => 'rw' );
1577             has transliteration => ( is => 'rw' );
1578              
1579             has encoding => ( is => 'rw' );
1580             has point => ( is => 'rw' );
1581             has keyDate => ( is => 'rw' );
1582             has qualifier => ( is => 'rw' );
1583             has _body => ( is => 'rw' );
1584              
1585             package MODS::Element::RecordChangeDate;
1586              
1587 2     2   304 use Moo;
  2         2  
  2         8  
1588              
1589             with('MODS::Record::Util');
1590              
1591 2     2   516 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         10  
  0         0  
1592              
1593             has lang => ( is => 'rw' );
1594             has xml_lang => ( is => 'rw' );
1595             has script => ( is => 'rw' );
1596             has transliteration => ( is => 'rw' );
1597              
1598             has encoding => ( is => 'rw' );
1599             has point => ( is => 'rw' );
1600             has keyDate => ( is => 'rw' );
1601             has qualifier => ( is => 'rw' );
1602             has _body => ( is => 'rw' );
1603              
1604             package MODS::Element::RecordIdentifier;
1605              
1606 2     2   255 use Moo;
  2         3  
  2         9  
1607              
1608             with('MODS::Record::Util');
1609              
1610 2     2   543 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         15  
  0         0  
1611              
1612             has lang => ( is => 'rw' );
1613             has xml_lang => ( is => 'rw' );
1614             has script => ( is => 'rw' );
1615             has transliteration => ( is => 'rw' );
1616              
1617             has source => ( is => 'rw' );
1618             has _body => ( is => 'rw' );
1619              
1620             package MODS::Element::RecordOrigin;
1621              
1622 2     2   202 use Moo;
  2         2  
  2         18  
1623              
1624             with('MODS::Record::Util');
1625              
1626 2     2   517 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         20  
  0         0  
1627              
1628             has lang => ( is => 'rw' );
1629             has xml_lang => ( is => 'rw' );
1630             has script => ( is => 'rw' );
1631             has transliteration => ( is => 'rw' );
1632              
1633             has _body => ( is => 'rw' );
1634              
1635             package MODS::Element::LanguageOfCataloging;
1636              
1637 2     2   230 use Moo;
  2         6  
  2         20  
1638              
1639             with('MODS::Record::Util');
1640              
1641             has objectPart => ( is => 'rw' );
1642             has altRepGroup => ( is => 'rw' );
1643             has usage => ( is => 'rw' );
1644             has displayLabel => ( is => 'rw' );
1645             has languageTerm => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1646             has scriptTerm => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1647              
1648             package MODS::Element::DescriptionStandard;
1649              
1650 2     2   627 use Moo;
  2         3  
  2         6  
1651              
1652             with('MODS::Record::Util');
1653              
1654 2     2   482 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         18  
  0         0  
1655              
1656             has lang => ( is => 'rw' );
1657             has xml_lang => ( is => 'rw' );
1658             has script => ( is => 'rw' );
1659             has transliteration => ( is => 'rw' );
1660              
1661             has authorityURI => ( is => 'rw' );
1662             has valueURI => ( is => 'rw' );
1663             has authority => ( is => 'rw' );
1664              
1665             has _body => ( is => 'rw' );
1666              
1667             package MODS::Element::RelatedItem;
1668              
1669 2     2   226 use Moo;
  2         2  
  2         7  
1670              
1671             with('MODS::Record::Util');
1672              
1673             has ID => ( is => 'rw' );
1674             has xlink => ( is => 'rw' );
1675             has displayLabel => ( is => 'rw' );
1676             has type => ( is => 'rw' );
1677              
1678             has titleInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1679             has name => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1680             has typeOfResource => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1681             has genre => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1682             has originInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1683             has language => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1684             has physicalDescription => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1685             has abstract => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1686             has tableOfContents => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1687             has targetAudience => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1688             has note => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1689             has subject => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1690             has classification => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1691             has relatedItem => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1692             has identifier => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1693             has location => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1694             has accessCondition => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1695             has part => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1696             has extension => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1697             has recordInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1698              
1699             package MODS::Element::Subject;
1700              
1701 2     2   1460 use Moo;
  2         4  
  2         13  
1702              
1703             with('MODS::Record::Util');
1704              
1705             has ID => ( is => 'rw' );
1706             has xlink => ( is => 'rw' );
1707             has displayLabel => ( is => 'rw' );
1708             has usage => ( is => 'rw' );
1709             has altRepGroup => ( is => 'rw' );
1710              
1711             has lang => ( is => 'rw' );
1712             has xml_lang => ( is => 'rw' );
1713             has script => ( is => 'rw' );
1714             has transliteration => ( is => 'rw' );
1715              
1716             has authorityURI => ( is => 'rw' );
1717             has valueURI => ( is => 'rw' );
1718             has authority => ( is => 'rw' );
1719              
1720             has topic => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1721             has geographic => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1722             has temporal => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1723             has titleInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1724             has name => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1725             has geographicCode => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1726             has genre => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1727             has hierarchicalGeographic => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1728             has cartographics => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1729             has occupation => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1730              
1731             package MODS::Element::Topic;
1732              
1733 2     2   1052 use Moo;
  2         3  
  2         8  
1734              
1735             with('MODS::Record::Util');
1736              
1737 2     2   533 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
1738              
1739             has lang => ( is => 'rw' );
1740             has xml_lang => ( is => 'rw' );
1741             has script => ( is => 'rw' );
1742             has transliteration => ( is => 'rw' );
1743              
1744             has authorityURI => ( is => 'rw' );
1745             has valueURI => ( is => 'rw' );
1746             has authority => ( is => 'rw' );
1747              
1748             has _body => ( is => 'rw' );
1749              
1750             package MODS::Element::Geographic;
1751              
1752 2     2   220 use Moo;
  2         3  
  2         8  
1753              
1754             with('MODS::Record::Util');
1755              
1756 2     2   559 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1757              
1758             has lang => ( is => 'rw' );
1759             has xml_lang => ( is => 'rw' );
1760             has script => ( is => 'rw' );
1761             has transliteration => ( is => 'rw' );
1762              
1763             has authorityURI => ( is => 'rw' );
1764             has valueURI => ( is => 'rw' );
1765             has authority => ( is => 'rw' );
1766              
1767             has _body => ( is => 'rw' );
1768              
1769             package MODS::Element::Temporal;
1770              
1771 2     2   221 use Moo;
  2         8  
  2         6  
1772              
1773             with('MODS::Record::Util');
1774              
1775 2     2   508 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         12  
  0         0  
1776              
1777             has lang => ( is => 'rw' );
1778             has xml_lang => ( is => 'rw' );
1779             has script => ( is => 'rw' );
1780             has transliteration => ( is => 'rw' );
1781              
1782             has authorityURI => ( is => 'rw' );
1783             has valueURI => ( is => 'rw' );
1784             has authority => ( is => 'rw' );
1785              
1786             has encoding => ( is => 'rw' );
1787             has point => ( is => 'rw' );
1788             has keyDate => ( is => 'rw' );
1789             has qualifier => ( is => 'rw' );
1790             has _body => ( is => 'rw' );
1791              
1792             package MODS::Element::GeographicCode;
1793              
1794 2     2   278 use Moo;
  2         7  
  2         7  
1795              
1796             with('MODS::Record::Util');
1797              
1798 2     2   497 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
1799              
1800             has lang => ( is => 'rw' );
1801             has xml_lang => ( is => 'rw' );
1802             has script => ( is => 'rw' );
1803             has transliteration => ( is => 'rw' );
1804              
1805             has authorityURI => ( is => 'rw' );
1806             has valueURI => ( is => 'rw' );
1807             has authority => ( is => 'rw' );
1808              
1809             has _body => ( is => 'rw' );
1810              
1811             package MODS::Element::HierarchicalGeographic;
1812              
1813 2     2   264 use Moo;
  2         4  
  2         10  
1814              
1815             with('MODS::Record::Util');
1816              
1817             has authorityURI => ( is => 'rw' );
1818             has valueURI => ( is => 'rw' );
1819             has authority => ( is => 'rw' );
1820              
1821             has continent => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1822             has country => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1823             has province => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1824             has region => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1825             has state => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1826             has territory => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1827             has county => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1828             has city => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1829             has island => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1830             has area => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1831             has extraterrestrialArea => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1832             has citySection => ( is => 'rw' , isa => \&_isa , default => sub { [] });
1833              
1834             package MODS::Element::Continent;
1835              
1836 2     2   1045 use Moo;
  2         3  
  2         8  
1837              
1838             with('MODS::Record::Util');
1839              
1840 2     2   496 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1841              
1842             has lang => ( is => 'rw' );
1843             has xml_lang => ( is => 'rw' );
1844             has script => ( is => 'rw' );
1845             has transliteration => ( is => 'rw' );
1846              
1847             has _body => ( is => 'rw' );
1848              
1849             package MODS::Element::Country;
1850              
1851 2     2   202 use Moo;
  2         5  
  2         10  
1852              
1853             with('MODS::Record::Util');
1854              
1855 2     2   483 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         16  
  0         0  
1856              
1857             has lang => ( is => 'rw' );
1858             has xml_lang => ( is => 'rw' );
1859             has script => ( is => 'rw' );
1860             has transliteration => ( is => 'rw' );
1861              
1862             has _body => ( is => 'rw' );
1863              
1864             package MODS::Element::Province;
1865              
1866 2     2   251 use Moo;
  2         3  
  2         6  
1867              
1868             with('MODS::Record::Util');
1869              
1870 2     2   567 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         10  
  0         0  
1871              
1872             has lang => ( is => 'rw' );
1873             has xml_lang => ( is => 'rw' );
1874             has script => ( is => 'rw' );
1875             has transliteration => ( is => 'rw' );
1876              
1877             has _body => ( is => 'rw' );
1878              
1879             package MODS::Element::Region;
1880              
1881 2     2   183 use Moo;
  2         2  
  2         13  
1882              
1883             with('MODS::Record::Util');
1884              
1885 2     2   487 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1886              
1887             has lang => ( is => 'rw' );
1888             has xml_lang => ( is => 'rw' );
1889             has script => ( is => 'rw' );
1890             has transliteration => ( is => 'rw' );
1891              
1892             has _body => ( is => 'rw' );
1893              
1894             package MODS::Element::State;
1895              
1896 2     2   177 use Moo;
  2         3  
  2         6  
1897              
1898             with('MODS::Record::Util');
1899              
1900 2     2   505 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1901              
1902             has lang => ( is => 'rw' );
1903             has xml_lang => ( is => 'rw' );
1904             has script => ( is => 'rw' );
1905             has transliteration => ( is => 'rw' );
1906              
1907             has _body => ( is => 'rw' );
1908              
1909             package MODS::Element::Territory;
1910              
1911 2     2   187 use Moo;
  2         4  
  2         6  
1912              
1913             with('MODS::Record::Util');
1914              
1915 2     2   546 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         11  
  0         0  
1916              
1917             has lang => ( is => 'rw' );
1918             has xml_lang => ( is => 'rw' );
1919             has script => ( is => 'rw' );
1920             has transliteration => ( is => 'rw' );
1921              
1922             has _body => ( is => 'rw' );
1923              
1924             package MODS::Element::County;
1925              
1926 2     2   177 use Moo;
  2         3  
  2         6  
1927              
1928             with('MODS::Record::Util');
1929              
1930 2     2   550 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
1931              
1932             has lang => ( is => 'rw' );
1933             has xml_lang => ( is => 'rw' );
1934             has script => ( is => 'rw' );
1935             has transliteration => ( is => 'rw' );
1936              
1937             has _body => ( is => 'rw' );
1938              
1939             package MODS::Element::City;
1940              
1941 2     2   195 use Moo;
  2         3  
  2         6  
1942              
1943             with('MODS::Record::Util');
1944              
1945 2     2   544 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   5  
  2         12  
  0         0  
1946              
1947             has lang => ( is => 'rw' );
1948             has xml_lang => ( is => 'rw' );
1949             has script => ( is => 'rw' );
1950             has transliteration => ( is => 'rw' );
1951              
1952             has _body => ( is => 'rw' );
1953              
1954             package MODS::Element::Island;
1955              
1956 2     2   203 use Moo;
  2         4  
  2         7  
1957              
1958             with('MODS::Record::Util');
1959              
1960 2     2   504 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
1961              
1962             has lang => ( is => 'rw' );
1963             has xml_lang => ( is => 'rw' );
1964             has script => ( is => 'rw' );
1965             has transliteration => ( is => 'rw' );
1966              
1967             has _body => ( is => 'rw' );
1968              
1969             package MODS::Element::Area;
1970              
1971 2     2   218 use Moo;
  2         4  
  2         10  
1972              
1973             with('MODS::Record::Util');
1974              
1975 2     2   487 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   8  
  2         14  
  0         0  
1976              
1977             has lang => ( is => 'rw' );
1978             has xml_lang => ( is => 'rw' );
1979             has script => ( is => 'rw' );
1980             has transliteration => ( is => 'rw' );
1981              
1982             has _body => ( is => 'rw' );
1983              
1984             package MODS::Element::ExtraterrestrialArea;
1985              
1986 2     2   175 use Moo;
  2         3  
  2         7  
1987              
1988             with('MODS::Record::Util');
1989              
1990 2     2   538 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         20  
  0         0  
1991              
1992             has lang => ( is => 'rw' );
1993             has xml_lang => ( is => 'rw' );
1994             has script => ( is => 'rw' );
1995             has transliteration => ( is => 'rw' );
1996              
1997             has _body => ( is => 'rw' );
1998              
1999             package MODS::Element::CitySection;
2000              
2001 2     2   183 use Moo;
  2         3  
  2         11  
2002              
2003             with('MODS::Record::Util');
2004              
2005 2     2   506 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   70  
  2         19  
  0         0  
2006              
2007             has lang => ( is => 'rw' );
2008             has xml_lang => ( is => 'rw' );
2009             has script => ( is => 'rw' );
2010             has transliteration => ( is => 'rw' );
2011              
2012             has _body => ( is => 'rw' );
2013              
2014             package MODS::Element::Occupation;
2015              
2016 2     2   185 use Moo;
  2         3  
  2         7  
2017              
2018             with('MODS::Record::Util');
2019              
2020 2     2   522 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         16  
  0         0  
2021              
2022             has lang => ( is => 'rw' );
2023             has xml_lang => ( is => 'rw' );
2024             has script => ( is => 'rw' );
2025             has transliteration => ( is => 'rw' );
2026              
2027             has authorityURI => ( is => 'rw' );
2028             has valueURI => ( is => 'rw' );
2029             has authority => ( is => 'rw' );
2030              
2031             has _body => ( is => 'rw' );
2032              
2033             package MODS::Element::Cartographics;
2034              
2035 2     2   268 use Moo;
  2         4  
  2         10  
2036              
2037             with('MODS::Record::Util');
2038              
2039             has scale => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2040             has projection => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2041             has coordinates => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2042              
2043             package MODS::Element::Scale;
2044              
2045 2     2   666 use Moo;
  2         87  
  2         8  
2046              
2047             with('MODS::Record::Util');
2048              
2049 2     2   507 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   9  
  2         15  
  0         0  
2050              
2051             has lang => ( is => 'rw' );
2052             has xml_lang => ( is => 'rw' );
2053             has script => ( is => 'rw' );
2054             has transliteration => ( is => 'rw' );
2055              
2056             has _body => ( is => 'rw' );
2057              
2058             package MODS::Element::Projection;
2059              
2060 2     2   192 use Moo;
  2         4  
  2         6  
2061              
2062             with('MODS::Record::Util');
2063              
2064 2     2   496 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
2065              
2066             has lang => ( is => 'rw' );
2067             has xml_lang => ( is => 'rw' );
2068             has script => ( is => 'rw' );
2069             has transliteration => ( is => 'rw' );
2070              
2071             has _body => ( is => 'rw' );
2072              
2073             package MODS::Element::Coordinates;
2074              
2075 2     2   242 use Moo;
  2         4  
  2         6  
2076              
2077             with('MODS::Record::Util');
2078              
2079 2     2   489 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
2080              
2081             has lang => ( is => 'rw' );
2082             has xml_lang => ( is => 'rw' );
2083             has script => ( is => 'rw' );
2084             has transliteration => ( is => 'rw' );
2085              
2086             has _body => ( is => 'rw' );
2087              
2088             package MODS::Element::TableOfContents;
2089              
2090 2     2   185 use Moo;
  2         3  
  2         7  
2091              
2092             with('MODS::Record::Util');
2093              
2094 2     2   517 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   2  
  2         11  
  0         0  
2095              
2096             has lang => ( is => 'rw' );
2097             has xml_lang => ( is => 'rw' );
2098             has script => ( is => 'rw' );
2099             has transliteration => ( is => 'rw' );
2100              
2101             has xlink => ( is => 'rw' );
2102             has displayLabel => ( is => 'rw' );
2103             has type => ( is => 'rw' );
2104             has shareable => ( is => 'rw' );
2105             has altRepGroup => ( is => 'rw' );
2106             has altFormat => ( is => 'rw' );
2107             has contentType => ( is => 'rw' );
2108             has _body => ( is => 'rw' );
2109              
2110             package MODS::Element::TargetAudience;
2111              
2112 2     2   299 use Moo;
  2         3  
  2         19  
2113              
2114             with('MODS::Record::Util');
2115              
2116 2     2   545 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         22  
  0         0  
2117              
2118             has lang => ( is => 'rw' );
2119             has xml_lang => ( is => 'rw' );
2120             has script => ( is => 'rw' );
2121             has transliteration => ( is => 'rw' );
2122              
2123             has authorityURI => ( is => 'rw' );
2124             has valueURI => ( is => 'rw' );
2125             has authority => ( is => 'rw' );
2126              
2127             has displayLabel => ( is => 'rw' );
2128             has altRepGroup => ( is => 'rw' );
2129              
2130             has _body => ( is => 'rw' );
2131              
2132             package MODS::Element::TitleInfo;
2133              
2134 2     2   290 use Moo;
  2         3  
  2         7  
2135              
2136             with('MODS::Record::Util');
2137              
2138             has lang => ( is => 'rw' );
2139             has xml_lang => ( is => 'rw' );
2140             has script => ( is => 'rw' );
2141             has transliteration => ( is => 'rw' );
2142              
2143             has authorityURI => ( is => 'rw' );
2144             has valueURI => ( is => 'rw' );
2145             has authority => ( is => 'rw' );
2146              
2147             has ID => ( is => 'rw' );
2148             has type => ( is => 'rw' );
2149             has otherType => ( is => 'rw' );
2150             has displayLabel => ( is => 'rw' );
2151             has supplied => ( is => 'rw' );
2152             has usage => ( is => 'rw' );
2153             has altRepGroup => ( is => 'rw' );
2154             has nameTitleGroup => ( is => 'rw' );
2155             has altFormat => ( is => 'rw' );
2156             has contentType => ( is => 'rw' );
2157              
2158             has title => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2159             has subTitle => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2160             has partNumber => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2161             has partName => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2162             has nonSort => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2163              
2164             package MODS::Element::Title;
2165              
2166 2     2   922 use Moo;
  2         4  
  2         7  
2167              
2168             with('MODS::Record::Util');
2169              
2170 2     2   505 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
2171              
2172             has lang => ( is => 'rw' );
2173             has xml_lang => ( is => 'rw' );
2174             has script => ( is => 'rw' );
2175             has transliteration => ( is => 'rw' );
2176              
2177             has _body => ( is => 'rw' );
2178              
2179             package MODS::Element::SubTitle;
2180              
2181 2     2   206 use Moo;
  2         2  
  2         7  
2182              
2183             with('MODS::Record::Util');
2184              
2185 2     2   536 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         14  
  0         0  
2186              
2187             has lang => ( is => 'rw' );
2188             has xml_lang => ( is => 'rw' );
2189             has script => ( is => 'rw' );
2190             has transliteration => ( is => 'rw' );
2191              
2192             has _body => ( is => 'rw' );
2193              
2194             package MODS::Element::PartNumber;
2195              
2196 2     2   201 use Moo;
  2         4  
  2         7  
2197              
2198             with('MODS::Record::Util');
2199              
2200 2     2   528 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         16  
  0         0  
2201              
2202             has lang => ( is => 'rw' );
2203             has xml_lang => ( is => 'rw' );
2204             has script => ( is => 'rw' );
2205             has transliteration => ( is => 'rw' );
2206              
2207             has _body => ( is => 'rw' );
2208              
2209             package MODS::Element::PartName;
2210              
2211 2     2   194 use Moo;
  2         2  
  2         7  
2212              
2213             with('MODS::Record::Util');
2214              
2215 2     2   512 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         10  
  0         0  
2216              
2217             has lang => ( is => 'rw' );
2218             has xml_lang => ( is => 'rw' );
2219             has script => ( is => 'rw' );
2220             has transliteration => ( is => 'rw' );
2221              
2222             has _body => ( is => 'rw' );
2223              
2224             package MODS::Element::NonSort;
2225              
2226 2     2   184 use Moo;
  2         3  
  2         7  
2227              
2228             with('MODS::Record::Util');
2229              
2230 2     2   519 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   3  
  2         12  
  0         0  
2231              
2232             has lang => ( is => 'rw' );
2233             has xml_lang => ( is => 'rw' );
2234             has script => ( is => 'rw' );
2235             has transliteration => ( is => 'rw' );
2236              
2237             has _body => ( is => 'rw' );
2238              
2239             package MODS::Element::TypeOfResource;
2240              
2241 2     2   280 use Moo;
  2         4  
  2         11  
2242              
2243             with('MODS::Record::Util');
2244              
2245 2     2   552 use overload fallback => 1 , '""' => sub { $_[0]->_body };
  2     0   4  
  2         10  
  0         0  
2246              
2247             has collection => ( is => 'rw' );
2248             has manuscript => ( is => 'rw' );
2249             has displayLabel => ( is => 'rw' );
2250             has usage => ( is => 'rw' );
2251             has altRepGroup => ( is => 'rw' );
2252              
2253             has _body => ( is => 'rw' );
2254              
2255             package MODS::Element::Mods;
2256              
2257 2     2   202 use Moo;
  2         3  
  2         8  
2258              
2259             with('MODS::Record::Util');
2260              
2261             has version => ( is => 'rw' , default => sub { "3.5"} );
2262             has ID => ( is => 'rw');
2263             has abstract => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2264             has accessCondition => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2265             has classification => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2266             has extension => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2267             has genre => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2268             has identifier => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2269             has language => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2270             has location => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2271             has name => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2272             has note => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2273             has originInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2274             has part => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2275             has physicalDescription => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2276             has recordInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2277             has relatedItem => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2278             has subject => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2279             has tableOfContents => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2280             has targetAudience => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2281             has titleInfo => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2282             has typeOfResource => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2283              
2284             package MODS::Element::ModsCollection;
2285              
2286 2     2   1399 use Moo;
  2         4  
  2         16  
2287              
2288             with('MODS::Record::Util');
2289              
2290             has mods => ( is => 'rw' , isa => \&_isa , default => sub { [] });
2291              
2292             package MODS::Parser;
2293              
2294 2     2   553 use Moo;
  2         2  
  2         6  
2295 2     2   4661 use XML::Parser;
  0            
  0            
2296             use JSON;
2297              
2298             with('MODS::Record::Util');
2299              
2300             our @stack = ();
2301             our $body;
2302             our $level = 0;
2303             our $flag = 0;
2304             our $count = 0;
2305              
2306             sub parse {
2307             my ($self,$source,$callback) = @_;
2308              
2309             @stack = ();
2310             $body = undef;
2311             $level = 0;
2312             $flag = 0;
2313             $count = 0;
2314              
2315             my $parser = XML::Parser->new(Handlers => {
2316             Start => \&start ,
2317             Char => \&char,
2318             End => \&end ,
2319             } , 'Non-Expat-Options' => { callback => $callback });
2320              
2321             $parser->parse($source);
2322              
2323             if (defined $callback) {
2324             $count;
2325             }
2326             else {
2327             $stack[0];
2328             }
2329             }
2330              
2331             sub parse_json {
2332             my ($self, $source, $callback) = @_;
2333              
2334             if (ref($source) =~ /^IO::/) {
2335             if (defined $callback) {
2336             my $count = 0;
2337             while(<$source>) {
2338             $callback->(_parse_json($_));
2339             $count++;
2340             }
2341             $count;
2342             }
2343             else {
2344             local $/;
2345             my $json_txt = <$source>;
2346             _parse_json($json_txt);
2347             }
2348             }
2349             elsif (defined $callback) {
2350             my $count = 0;
2351             for (split(/\n/,$source)) {
2352             $callback->(_parse_json($_));
2353             $count++;
2354             }
2355             $count;
2356             }
2357             else {
2358             _parse_json($source);
2359             }
2360             }
2361              
2362             sub _parse_json {
2363             my $json_txt = shift;
2364             my $perl = JSON->new->utf8(1)->decode($json_txt);
2365              
2366             _bless_object($perl);
2367              
2368             [ %{ $perl } ]->[1];
2369             }
2370              
2371             sub _bless_object {
2372             my $obj = shift;
2373              
2374             return unless ref($obj) =~ /^HASH|MODS::Element/;
2375              
2376             for (keys %$obj) {
2377             my $val = $obj->{$_};
2378             my $class = $_;
2379             $class =~ s{^(.)}{uc($1)}e;
2380             $class = "MODS::Element::$class";
2381              
2382             if (ref($val) eq 'ARRAY') {
2383             for (@{$val}) {
2384             _bless_object(bless($_,$class));
2385             }
2386             }
2387             elsif (ref($val) eq 'HASH') {
2388             _bless_object(bless($val,$class));
2389             }
2390             }
2391             }
2392              
2393             sub start {
2394             my ($expat,$element,%attrs) = @_;
2395             my $local_name = $element; $local_name =~ s/^\w+://;
2396             my $e;
2397              
2398             if ($level) {
2399             $level++;
2400             }
2401             elsif (@stack == 0) {
2402             my $module = $local_name;
2403             $module =~ s{^(.)}{uc($1)}e;
2404             $module = "MODS::Element::$module";
2405             $e = $module->new(%attrs);
2406             $body = undef;
2407             push(@stack,$e);
2408             }
2409             else {
2410             my $method = "add_$local_name";
2411             my $module = $local_name;
2412             $module =~ s{^(.)}{uc($1)}e;
2413             $module = "MODS::Element::$module";
2414              
2415             # Start recording literal XML if we find an element we cant recognize...
2416             if ($stack[-1]->can($local_name)) {
2417             $e = $stack[-1]->$method($module->new(%attrs));
2418             $body = undef;
2419              
2420             push(@stack,$e);
2421             }
2422             else {
2423             die "$element not allowed in " . ref($stack[-1]) unless ref($stack[-1]) =~ /^MODS::Element::(AccessCondition|Extension)$/;
2424             $level++;
2425             }
2426             }
2427              
2428             if ($level) {
2429             $body .= "<$element";
2430             for (keys %attrs) {
2431             $body .= " $_=\"" . escape($attrs{$_}) . "\"";
2432             }
2433             $body .= ">";
2434             }
2435             }
2436              
2437             sub char {
2438             my ($expat,$string) = @_;
2439              
2440             $body .= $string;
2441             }
2442              
2443             sub end {
2444             my ($expat,$element,%attrs) = @_;
2445             my $local_name = $element; $local_name =~ s/^\w+://;
2446             my $callback = $expat->{'Non-Expat-Options'}->{'callback'};
2447              
2448             if ($level) {
2449             $body .= "";
2450             $level--;
2451             $flag = 1;
2452             }
2453             else {
2454             $body = MODS::Record::Xml_String->new(_body => $body) if $flag;
2455            
2456             $flag = 0;
2457              
2458             $stack[-1]->_body($body) if $stack[-1]->can('_body');
2459              
2460             $body = undef;
2461            
2462             if ($local_name eq 'mods' && defined $callback) {
2463             $count++;
2464             $callback->(pop(@stack));
2465             }
2466             else {
2467             pop(@stack) unless @stack == 1;
2468             }
2469             }
2470             }
2471              
2472             sub debug {
2473             my $msg = shift;
2474             print STDERR "$msg\n";
2475             print STDERR "level: $level\n";
2476             print STDERR "flag: $flag\n";
2477             for (@stack) {
2478             printf STDERR "%s\n" , ref $_;
2479             }
2480             print STDERR "---\n";
2481             }
2482              
2483             1;