1 package OpenILS::Application::Cat::Utils;
2 use strict; use warnings;
3 use OpenILS::Application::AppUtils;
4 use OpenILS::Utils::Fieldmapper;
7 use OpenSRF::Utils::SettingsParser;
8 use OpenILS::Utils::FlatXML;
9 use OpenILS::Application::WORM;
11 my $utils = OpenILS::Application::Cat::Utils->new();
13 my $parser = XML::LibXML->new();
14 my $xslt = XML::LibXSLT->new();
15 my $xslt_doc = $parser->parse_file( "/pines/cvs/ILS/Open-ILS/xsl/MARC21slim2MODS.xsl" );
16 my $mods_sheet = $xslt->parse_stylesheet( $xslt_doc );
18 my $isbn_xpath = "//mods:mods/mods:identifier[\@type='isbn']";
20 my $resource_xpath = "//mods:mods/mods:typeOfResource";
22 my $pub_xpath = "//mods:mods/mods:originInfo//mods:dateIssued[\@encoding='marc']|" .
23 "//mods:mods/mods:originInfo//mods:dateIssued[1]";
25 my $tcn_xpath = "//mods:mods/mods:recordInfo/mods:recordIdentifier";
26 my $publisher_xpath = "//mods:mods/mods:originInfo//mods:publisher[1]";
31 $class = ref($class) || $class;
32 return bless( {}, $class );
36 # ---------------------------------------------------------------------------
37 # Converts an XML nodeset into a tree
38 # This method expects a blessed Fieldmapper::biblio::record_node object
40 my($class, $nodeset) = @_;
42 for my $child (@$nodeset) {
43 next unless ($child and defined($child->parent_node));
44 my $parent = $nodeset->[$child->parent_node];
46 warn "No Parent For " . $child->intra_doc_id() . "\n";
48 $parent->children([]) unless defined($parent->children);
51 push( @{$parent->children}, $child );
58 # ---------------------------------------------------------------------------
59 # Converts a tree into an xml nodeset
60 # This method expects a blessed Fieldmapper::biblio::record_node object
64 my($self, $node, $newnodes) = @_;
65 return $newnodes unless $node;
67 if(!$newnodes) { $newnodes = []; }
68 push( @$newnodes, $node );
70 if( $node->children() ) {
72 for my $child (@{ $node->children() }) {
74 new Fieldmapper::biblio::record_node ($child);
75 if(!defined($child->parent_node)) {
76 $child->parent_node($node->intra_doc_id);
77 $child->ischanged(1); #just to be sure
79 $self->tree2nodeset( $child, $newnodes );
83 $node->children([]); #we don't need them hanging around
88 # Removes any deleted nodes from the tree
91 my($self, $nodeset) = @_;
93 for my $node (@$nodeset) {
94 if(!$node->isdeleted() ) {
95 push @newnodes, $node;
105 # ---------------------------------------------------------------------------
106 # Grabs the data 'we want' from the MODS doc and returns it in hash form
107 # ---------------------------------------------------------------------------
108 sub mods_values_to_mods_slim {
109 my( $self, $modsperl ) = @_;
115 my $tmp = $modsperl->{title};
117 if(!$tmp) { $title = ""; }
119 ($title = $tmp->{proper}) ||
120 ($title = $tmp->{translated}) ||
121 ($title = $tmp->{abbreviated}) ||
122 ($title = $tmp->{uniform});
125 $tmp = $modsperl->{author};
126 if(!$tmp) { $author = ""; }
128 ($author = $tmp->{personal}) ||
129 ($author = $tmp->{other}) ||
130 ($author = $tmp->{corporate}) ||
131 ($author = $tmp->{conference});
134 $tmp = $modsperl->{subject};
135 if(!$tmp) { $subject = []; }
137 for my $key( keys %{$tmp}) {
138 push(@$subject, $tmp->{$key}) if $tmp->{$key};
142 return { title => $title, author => $author, subject => $subject };
146 sub _marcxml_to_perl {
147 my($self, $marcxml) = @_;
148 my $xmldoc = $parser->parse_string( $marcxml );
149 my $mods = $mods_sheet->transform($xmldoc);
150 my $perl = OpenSRF::Utils::SettingsParser::XML2perl( $mods->documentElement );
151 return $perl->{mods} if exists($perl->{mods});
156 # ---------------------------------------------------------------------------
157 # Initializes a MARC -> Unified MODS batch process
158 # ---------------------------------------------------------------------------
160 sub start_mods_batch {
162 my( $self, $master_doc ) = @_;
164 $self = new OpenILS::Application::Cat::Utils;
167 my $xmldoc = $parser->parse_string($master_doc);
168 my $mods = $mods_sheet->transform($xmldoc);
170 $self->{master_doc} = OpenILS::Application::WORM->modsdoc_to_values( $mods );
171 $self->{master_doc} = $utils->mods_values_to_mods_slim( $self->{master_doc} );
173 $self->{master_doc}->{isbn} =
174 OpenILS::Application::WORM::_get_field_value( $mods, $isbn_xpath );
176 $self->{master_doc}->{type_of_resource} =
177 [ OpenILS::Application::WORM::_get_field_value( $mods, $resource_xpath ) ];
179 $self->{master_doc}->{tcn} =
180 OpenILS::Application::WORM::_get_field_value( $mods, $tcn_xpath );
182 $self->{master_doc}->{pubdate} =
183 OpenILS::Application::WORM::_get_field_value( $mods, $pub_xpath );
185 $self->{master_doc}->{publisher} =
186 OpenILS::Application::WORM::_get_field_value( $mods, $publisher_xpath );
190 # ---------------------------------------------------------------------------
191 # Takes a MARCXML string and adds it to the growing MODS doc
192 # ---------------------------------------------------------------------------
193 sub push_mods_batch {
194 my( $self, $marcxml ) = @_;
196 my $xmldoc = $parser->parse_string($marcxml);
197 my $mods = $mods_sheet->transform($xmldoc);
199 my $xmlperl = OpenILS::Application::WORM->modsdoc_to_values( $mods );
200 $xmlperl = $utils->mods_values_to_mods_slim( $xmlperl );
202 for my $subject( @{$xmlperl->{subject}} ) {
203 push @{$self->{master_doc}->{subject}}, $subject;
206 push( @{$self->{master_doc}->{type_of_resource}},
207 OpenILS::Application::WORM::_get_field_value( $mods, $resource_xpath ));
209 if(!($self->{master_doc}->{isbn}) ) {
210 $self->{master_doc}->{isbn} =
211 OpenILS::Application::WORM::_get_field_value( $mods, $isbn_xpath );
216 # ---------------------------------------------------------------------------
217 # Completes a MARC -> Unified MODS batch process and returns the perl hash
218 # ---------------------------------------------------------------------------
219 sub finish_mods_batch {
221 my $perl = $self->{master_doc};
222 $self->{master_doc} = undef;