NAME
    MODS::Record - Perl extension for handling MODS records

SYNOPSIS
     use MODS::Record qw(xml_string);

     my $mods = MODS::Record->new;

     my $collection = MODS::Collection->new;

     my $mods = $collection->add_mods(ID => '1234');

     $mods->add_abstract("Hello", lang => 'eng');
     $mods->add_abstract("Bonjour", lang => 'fra');

     # Set a deeply nested field...
     $mods->add_language()->add_languageTerm('eng');

     # Set a list of deeply nested fields...
     $mods->add_location(sub {
            $_[0]->add_physicalLocation('here');
            $_[0]->add_shelfLocation('here too');
            $_[0]->add_url('http://here.org/there');
     }); 

     # Set an inline XML extension...
     $mods->add_accessCondition(xml_string("<x:foo><x:bar>21212</x:bar></x:foo>"));

     # Retrieve a field by a filter...
     $mods->get_abstract(lang => 'fra')->body("Bonjour :)");
     $mods->get_abstract(lang => 'fra')->contentType('text/plain');

     for ($mods->get_abstract(lang => 'fra')) {
            printf "%s\n" , $_->body;
     }

     # Set a field to a new value
     my @newabstract;
     for ($mods->get_abstract) {
            push @newabstract, $_ unless $_->lang eq 'fra';
     }
     $mods->set_abstract(@newabstract);

     # Clear all abstracts;
     $mods->set_abstract(undef);

     # Serialize
     print $mods->as_json(pretty => 1);
     print $mods->as_xml;

     # Deserialize
     my $mods = MODS::Record->from_xml(IO::File->new('mods.xml'));
     my $mods = MODS::Record->from_json(IO::File->new('mods.js'));

DESCRIPTION
    This module provides MODS (http://www.loc.gov/standards/mods/) parsing
    and creation for MODS Schema 3.5.

METHODS
  MODS::Record->new(%attribs)
  MODS::Collection->new(%attribs)
    Create a new MODS record or collection. Optionally attributes can be
    provided as defined by the MODS specification. E.g.

     $mods = MODS::Record->new(ID='123');

  add_xxx()
    Add a new element to the record where 'xxx' is the name of a MODS
    element (e.g. titleInfo, name, genre, etc). This method returns an
    instance of the added MODS element. E.g.

     $titleInfo = $mods->add_titleInfo; # $titleInfo is a 'MODS::Element::TitleInfo'

  add_xxx($text,%attribs)
    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 and optionally
    provide further attributes. This method returns an instance of the added
    MODS element. E.g.

     $mods->add_abstract("My abstract", lang=>'eng');

  add_xxx(sub { })
    Add a new element to the record where 'xxx' is the name of a MODS
    element. The provided coderef gets as input an instance of the added
    MODS element. This method returns an instance of the added MODS element.
    E.g.

     $mods->add_abstract(sub {
            my $o = shift;
            $o->body("My abstract");
            $o->lang("eng");
     })

  add_xxx($obj)
    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 class (where
    Xxx is the corresponding MODS element). This method returns an instance
    of the added MODS element. E.g.

     $mods->add_abstract(
            MODS::Element::Abstract->new(_body=>'My abstract', lang=>'eng')
     );

  get_xxx()
  get_xxx(%filter)
  get_xxx(sub { })
    Retrieve an element from the record where 'xxx' is the name of a MODS
    element. This methods return in array context all the matching elements
    or the first match in scalar context. Optionally provide a %filter or a
    coderef filter function. E.g.

     @titles = $mods->get_titleInfo();
     $alt    = $mods->get_titleInfo(type=>'alternate');
     $alt    = $mods->get_titleInfo(sub { shift->type eq 'alternate'});

  set_xxxx()
  set_xxx(undef)
  set_xxx($array_ref)
  set_xxx($xxx1,$xxx2,...)
    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 is a null
    operation. When undef als argument is provided, then the element is
    deleted. To overwrite the existing content of the element an ARRAY (ref)
    of MODS::Element::Xxx can be provided (where 'Xxx' is the corresponding
    MODS element). E.g.

     # Delete all abstracts
     $mods->abstract(undef);

     # Set all abstracts
     $mods->abstract(MODS::Element::Abstract->new(), MODS::Element::Abstract->new(), ...);
     $mods->abstract([ MODS::Element::Abstract->new(), MODS::Element::Abstract->new(), ... ]);

  as_xml()
  as_xml(xml_prolog=>1)
    Return the record as XML.

  from_xml($string)
  from_xml(IO::Handle)
    Parse an XML string or IO::Handle into a MODS::Record.

  as_json()
  as_json(pretty=>1)
    Return the record as JSON string.

  from_json($string)
  from_json(IO::Handle)
    Parse and JSON string or JSON::Handle into a MODS::Record.

SEE ALSO
    *   Library Of Congress MODS pages (http://www.loc.gov/standards/mods/)

DESIGN NOTES
    *   I'm not a MODS expert

    *   I needed a MODS module to parse and create MODS records for our
        institutional repository

    *   This module is not created for speed

    *   This module doesn't have any notion of ordering of MODS elements
        themselves (e.g. first 'titleInfo', then 'name'). But each
        sub-element keeps its original order (e.g. each 'title' in
        'titleInfo').

AUTHORS
    *   Patrick Hochstenbach <Patrick . Hochstenbach at UGent . be>