LP#1576727: Delimit bib CN subfields with a space
authorMike Rylander <mrylander@gmail.com>
Fri, 29 Apr 2016 19:30:17 +0000 (15:30 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Tue, 1 May 2018 18:20:23 +0000 (14:20 -0400)
When suggested call numbers are pulled from a bib record, space delimiters are
dropped.  This is bad for noralization routines.  Now we will forcibly inject
a space between subfield values.

Also included are two small optimizations: exit early if no nodes are found
for a particular bib CN definition; use map+join instead of a for loop and
blind substring trim to stitch together an xpath expression.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Cesar Velez <cesar.velez@equinoxinitiative.org>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm

index f88cc45..95a748a 100644 (file)
@@ -528,6 +528,7 @@ sub biblio_record_marc_cn {
         my $tag = substr($field, 0, 3);
         $logger->debug("Tag = $tag");
         my @node = $doc->findnodes("//marc:datafield[\@tag='$tag']");
+        next unless (@node);
 
         # Now parse the subfields and build up the subfield XPath
         my @subfields = split(//, substr($field, 3));
@@ -536,16 +537,17 @@ sub biblio_record_marc_cn {
         if (!@subfields) {
             @subfields = ('a');
         }
-        my $subxpath;
-        foreach my $sf (@subfields) {
-            $subxpath .= "\@code='$sf' or ";
-        }
-        $subxpath = substr($subxpath, 0, -4);
-        $logger->debug("subxpath = $subxpath");
+        my $xpath = 'marc:subfield[' . join(' or ', map { "\@code='$_'" } @subfields) . ']';
+        $logger->debug("xpath = $xpath");
 
         # Find the contents of the specified subfields
         foreach my $x (@node) {
-            my $cn = $x->findvalue("marc:subfield[$subxpath]");
+            # We can't use find($xpath)->to_literal_delimited here because older 2.x
+            # versions of the XML::LibXML module don't have to_literal_delimited().
+            my $cn = join(
+                ' ',
+                map { $_->textContent } $x->findnodes($xpath)
+            );
             push @res, {$tag => $cn} if ($cn);
         }
     }