Tech Blog

Primo VE Normalization Rule Examples

See also: Configuring Normalization Rules for Display and Local Fields

For additional examples of customized Primo VE Normalization Rules see also the Github list of customized Primo VE normalization rules from Colin Bitter

Note –  If you copy/paste, make sure that the quotation marks transfer correctly.

Create a hypertext link

Create hypertext link from the URL stored in the MARC 505 field and display it in the Contents display field.

 

 

Remove ‘Online’ indication from the title

This rule is the OTB title rule, with an addition row to remove the online indication.

Display title from  524 field  (in addition to OTB Title rule)

rule "Primo VE - Title"
when
       MARCRECORD AND
       MARC is "524"."a"
then
       set TEMP"1" to prima display title
       set TEMP"2" to MARC."524"."a"
       remove string (TEMP"1","<<")
       remove string (TEMP"1",">>")
       remove substring using regex (TEMP"1","(,|/|:|;|=)+$")
       concatenate with delimiter (TEMP"1",TEMP"2"," -- ")
       create pnx."display"."title" with TEMP"1"
end

rule "Primo VE - Title1"
when
        MARCRECORD AND NOT
        MARC is "524"
then
  set TEMP"1" to prima display title
        remove string (TEMP"1","<<")
        remove string (TEMP"1",">>")
        remove substring using regex (TEMP"1","(,|/|:|;|=)+$")
  create pnx."display"."title" with TEMP"1"
end

 

Check that both subfields ‘a’ and ‘b’ exist

when
        MARC."245" has any "a,b"
then
        create pnx."display"."lds05" with MARC."245" subfields "a,b"

 

Display Contributor from 700 field

rule "Primo VE Display - contributor 700"
  when
     MARC."700" has any "a,b,c,d,e,j,q,u" AND
     MARC.control is "001"
  then
          set TEMP"1" to MARC."700" sub without sort "a,b,c,d,e,j,q,u"
           remove substring using regex (TEMP"1","(/|:|;|=|,)+$")
           set TEMP"2" to MARC."700" sub without sort "a"
           remove substring using regex (TEMP"2","(/|:|;|=|,)+$")
           add prefix (TEMP"2","$$Q")
           remove substring using regex (TEMP"2","^$$Q$")
           concatenate with delimiter (TEMP"1",TEMP"2","")
           set TEMP"3" to multilingual by "700" "Contributor" "display"
       concatenate with delimiter (TEMP"1",TEMP"3","")
           create pnx."display"."contributor" with TEMP"1"
end

 

Display Creation date from 260 field

rule "Primo VE - Date Of Publication 260/3"
priority 40
  when
    MARC is "260"."c" AND
    MARC."260".ind"1"  equals "3"
  then
      set TEMP"1" to MARC."260"."c"
      remove substring using regex (TEMP"1","[+")
      remove substring using regex (TEMP"1","(]|:|,|=|/|.)+$")
     	remove substring using regex (TEMP"1","(])+")
    set pnx."display"."creationdate" to TEMP"1"
end

 

Display Edition from 250 field

rule "Primo VE - Complete Edition 250"
  when
    MARC."250" has any "3,a,b"
  then
    create pnx."display"."edition" with MARC."250" sub without sort "3,a,b"
end

 

Display Format from 254 field

rule "Primo VE - Format 254"
  when
    MARC is "254"
  then
      set TEMP"1" to MARC."254" excluding num subfields without sort
      add prefix (TEMP"1","254 ")
    create pnx."display"."format" with TEMP"1"
end

 

Display ispartof from 773 field

rule "Primo VE - Ispartof 773"
  when
        MARC is "773"."t"
  then
    set TEMP"1" to MARC "773" excluding subfields without sorting "u|w|x|y|z"
    set TEMP"2" to MARC."773"."t"
    remove substring using regex (TEMP"2","(/|:|;|=|,)+$")
        add prefix (TEMP"2","$$Q")
        remove substring using regex (TEMP"2","^$$Q$")
        set TEMP"3" to MARC."773" prima_w_relation "w"
    set TEMP"4" to MARC."773" prima_x_relation "x"
    set TEMP"5" to MARC."773" prima_x_relation "z"
        concatenate with delimiter (TEMP"1",TEMP"2","")
        concatenate with delimiter (TEMP"1",TEMP"3","")
    concatenate with delimiter (TEMP"1",TEMP"4","")
    concatenate with delimiter (TEMP"1",TEMP"5","")
        create pnx."display"."ispartof" with TEMP"1"
end

 

Display Related work from 700 field

rule "Primo VE - Related Work 700"
  when
    MARC."700" has any "t" AND NOT
    MARC."700".ind"2"  equals "2"
  then
    set TEMP"1" to MARC."700" subfields "i"
    set TEMP"2" to MARC."700"  excluding subfields without sorting "[0-9]|x|i|="
    concatenate existing with delimiter (TEMP"1",TEMP"2"," ")
    set TEMP"3" to MARC."700" excluding subfields without sorting "[0-9]|x|i|=|f"
    add prefix (TEMP"3","$$Q")
        remove substring using regex (TEMP"3","^$$Q$")
        concatenate with delimiter (TEMP"1",TEMP"3","")
        create pnx."display"."related_work" with TEMP"1"
end

 

Display multiple occurrences of 264 field

The OTB rule uses ‘set’ to create the field. If the record had more than one 264 field, ‘set’ would create a single field and overwrite it each time another 264 field was found in the record. Changing the action to ‘create’ allows you to write multiple occurrence of a field.

rule "Primo VE - publisher 264/3/1"
priority 20
  when
    MARC."264" has any "a,b"
  then
      set TEMP"1" to MARC."264" sub without sort "a,b"
      remove string (TEMP"1","<<")
        remove string (TEMP"1",">>")
        remove string (TEMP"1","(")
        remove string (TEMP"1",")")
        remove string (TEMP"1","[")
        remove string (TEMP"1","]")
        remove leading and trailing spaces (TEMP"1")
        remove substring using regex (TEMP"1","(/|:|;|=|,)+$")
        replace spaces (TEMP"1"," ")
    create pnx."display"."publisher" with TEMP"1"
end

 

Display creator  so the names will be in natural order (FirstName LastName)

In Marc21 records, personal names are in inverted order separated by comma (LastName, FirstName). This rule changes the order.

rule "Primo VE Display - Creator Fixed"
    		when
        	MARC is "100"."a"
    		then
        	set TEMP"1" to MARC."100" sub without sort "a"
        	set TEMP"2" to MARC."100" sub without sort "a"
               set TEMP"3" to MARC."100" sub without sort "a"
        	remove substring using regex (TEMP"1","^([^,]*)")
        	remove substring using regex (TEMP"2",",.*$")
               remove substring using regex (TEMP"1","[,]")
        	concatenate with delimiter (TEMP"1",TEMP"2"," ")
               add prefix (TEMP"3","$$Q")
               concatenate with delimiter (TEMP"1",TEMP"3"," ")
       	 set pnx."display"."lds04" to TEMP"1"
end        

 

Display title from field 130 $a if exist – else display from 245 subfields a,b,c

rule "Primo VE - Title"
  when
    MARC is "130"."a"

then
    create pnx."display"."title" with MARC "130"."a"
end

rule "Primo VE - Title1"
  when
    MARC."245" has any "a,b,c" AND NOT
    MARC is "130"

then
    create pnx."display"."title" with MARC "245" subfields "a,b,c"
end

 

Display only 650 fields with subfield 2 is ‘ilot’

rule "Primo VE Display- Subject 650"
       when
          	 MARC."650" has any "a-u,w-z" AND                
          	 MARC."650"."2" match "ilot"           
       then
                 set TEMP"1" to MARC."650" subfields "a-u,w" delimited by " " remove substring using regex ".+$"
                 set TEMP"2" to MARC."650" sub without sorting "x-z" delimited by " -- "
        	remove substring using regex (TEMP"2",".+$")                
        	concatenate with delimiter (TEMP"1",TEMP"2"," -- ")
       	create pnx."display"."subject" with TEMP"1"
end

 

Display contents field with sorted subfields

rule "Primo VE - contents 505"
  when
    MARC."505" has any "a-z" 
  then
    create pnx."display"."contents" with MARC."505" subfields "a-z"
end

 

Display contents field without sorting subfields

rule "Primo VE - contents 505"
  when
    MARC is "505"
  then
    create pnx."display"."contents" with MARC "505" excluding num subfields without sort
end

 

Check the LDR field in the source records

rule "Primo VE - LDR check"
when
   MARC is "130"."a" AND
   MARC.control."LDR"(6-7) matches "ab|ai|as"
then
   create pnx."display"."title" with MARC."130"."a"
end

 

Display Creation date from 260 field when ind 1 equals 3

rule "Primo VE - Date Of Publication 260/3"
  when
    MARC is "260"."c" AND
    MARC."260".ind"1"  equals "3"
  then
      set TEMP"1" to MARC."260"."c"
      remove substring using regex (TEMP"1","(:|,|=|/|.)+$")
    set pnx."display"."creationdate" to TEMP"1"
end

 

Display 246 field only if it doesn’t hold $$5 OCLC.

rule "Primo VE - addtitle 246"
            when
                        MARC."246" has any "i,a,b,f,g,n,p" AND NOT
                        MARC."246"."5" match "OCLC"
            then
                        create pnx."display"."addtitle" with MARC."246" sub without sort "i,a,b,f,g,n,p"
end

 

Display description with 520 field $a only if 999 $a is YES. Else display 520 $b

rule "Prima_Display - 520 - 999 yes"
    when
                MARC "520" has any "a,b" AND 
               	MARC."999"."a" equals "YES"
    then
               	create pnx."display"."description" with MARC "520" sub without sort "a"
end
 
 
rule "Prima_Display - 520 - 999 no"
    when
                MARC "520" has any "a,b" AND NOT
               	MARC."999"."a" equals "YES"
    then
               	create pnx."display"."description" with MARC "520" sub without sort "b"
end

 

Display 382 field whether or not subfield 3 exist.

rule "Primo VE - Lds02"
       when
              MARC."382" has any "a,b,e,n" AND 
              MARC."382"."3" match ".*"
       then
                set TEMP"1" to MARC."382" subfields "3"
                add suffix (TEMP"1",":")
                set TEMP"2" to MARC."382" sub without sort "a,b,e,n"
                replace string by string (TEMP"2","( [0-9]){2}"," $1")
                replace string by string (TEMP"2"," ([0-9]{1})"," ($1);")
                replace string by string (TEMP"2",";$","")
                concatenate with delimiter  (TEMP"1",TEMP"2"," ")
              create pnx."display"."lds02" with TEMP"1"
end

rule "Primo VE - Lds02/2"    
   when
              MARC."382" has any "a,b,e,n" AND NOT
              MARC."382"."3" match ".*"
   then
                set TEMP"1" to MARC."382" sub without sort "a,b,e,n"
                replace string by string (TEMP"1","( [0-9]){2}"," $1")
                replace string by string (TEMP"1"," ([0-9]{1})"," ($1);")
                replace string by string (TEMP"1",";$","")
               create pnx."display"."lds02" with TEMP"1"
end

 

Create local field for search lsr01 with values from MARC 300 subfields  a,b

rule "Primo VE Marc - Lsr01"
when
  MARC.”300” has any "a,b"
then
  create pnx."search"."lsr01" with MARC "300" subfields "a,b"
end

 

Create local field for display with values from MARC 583 subfield a

rule "Primo VE - Lds02"
when
  MARC is "583"."a"
then
  create pnx."display"."lds02" with MARC."583"."a"
end

Hide field content when there are conditions on multiple fields (using java)

rule "Primo VE - Lds02"
when
MARC is "035"."a" AND
MARC."035"."a" match "(CKB).*"
then
set pnx."display"."lds02" to "<span style=display:none;></span>"
end

Please note that in this example,  in case field 035 $$a = CKB – the field title will be display – only the value will be hidden.

Display constant text when the condition is true

rule "Primo VE - Lds11"
when
MARC.control."008"(22-23) equals "j"
then
set TEMP"1" to position("008",22-23)
add prefix (TEMP"1","barnlitt") 
remove string (TEMP"1","j") 
set pnx."display"."lds11" to TEMP"1"
end

Display Subject 650 field $a only if it ends with ‘ology’ (using regex)

rule "Primo VE - Lds99"
when
MARC is "650"."a"
then 
set TEMP"1" to MARC."650"."a"
return list using regex (TEMP"2",TEMP"1",".*ology")
create pnx."display"."lds99" with list TEMP"2"
end

Add parentheses to to one of the subfields in local field

The field is: 900 $$a Professor Alicia Chen $$b 000613

The rule will display: Professor Alicia Chen (000613)

Instead of: Professor Alicia Chen 000613

rule "Primo VE - Lds01"
   when
MARC."900" has any "a,b"
   then
                set TEMP"1" to MARC."900" subfields "a"
                set TEMP"2" to MARC."900" subfields "b"
                add suffix (TEMP"2",")")
                add prefix (TEMP"2","(")
                concatenate with delimiter (TEMP"1",TEMP"2","")
                create pnx."display"."lds01" with TEMP"1"
end

Make the 505 contents note display a line break instead of two dashes (–) between subfield t occurrences

The field is: 50500 |t Agunot — |t Tales of Childhood : |t The kerchief — |t Two pairs

The OTB rule will display it as follows: Agunot — Tales of Childhood : — The kerchief — Two pairs

The normalization rule will change it to:

Agunot
Tales of Childhood :
The kerchief
Two pairs

rule "Primo VE - contents 505"
  when
                MARC is "505"."t"
  then
                set TEMP"1" to MARC."505" sub without sort "t"
                replace string by string (TEMP"1","(--|;)","<br>")
                create pnx."display"."contents" with TEMP"1"
end

Technical documentation about regular expression language we are using in Primo VE:

https://docs.oracle.com/javase/8/docs/api/java/util/regex/Matcher.html
https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html

Recommended online test tool that shows the regex as java string (which will match Primo VE):
https://www.regexplanet.com/advanced/java/index.html

23 Replies to “Primo VE Normalization Rule Examples”

  1. Applying the — Remove ‘Online’ indication from the title — rule does not appear to remove “(Online)” from the title. Instead it replaces “(Online)” with “()”.

  2. You are correct, thank you for noticed. It seems that there was a problem to save the rule here with two backslash (\\). The line should be as follows:
    remove string (TEMP”1″,”\\(Online\\)”)

    I have updated the example

  3. Hello,

    I have created a local field using search and facet normalization rules to make this field searchable in Primo and filterable by facets.

    But I don’t know how to configure the NR to get the information facets of this local field to display in Primo with the punctuation marks that separate the different subfields. I mean commas or parentheses, like in this example: 996 _ _ $$a Castillo, Antonio del $$c (llibreter), $$d 1758?-1806

    Thanks!!

  4. Hello Diana,

    Can you please specify exactly what would you like to be displayed in the facet value for this specific example?
    Also if you want more assistance with the rules you can submit a case to Support

    Thank you,
    Moran

  5. Hello Moran,

    Sorry! I think it’s enough that the facet value shows the information of the subfield “a” including the comma between the last name and the first name of the authority, as in the author / creator facet. To make it looks like this: Castillo, Antonio del.
    In the tests I have done, I can’t get the comma to appear in the facet value. It shows like this: Castillo Antonio del.
    How can I do that?

    Thanks for help. I will also consult Support

  6. Hello Moran,
    I think that what I really would like to know is if we can configure the display of facet value that is shown in Primo. Especially for local fields.
    Thanks a lot!

  7. Hello Diana,

    I suggest you open a support case so they will look at your specific data and they will give you the needed information to set it up.

    Regards,
    Moran

  8. Thank you for the examples! This is very helpful. For the 1st rule(create a hyperlink), ‘\’ needs to be added right before the quotation mark(“) for the HTML code as below; otherwise it gives a syntax error.

    add prefix (TEMP”1″,”“)

  9. Thank youoran, really helpful.

    There’s a typo in “Check that both subfields ‘a’ and ‘b’ exist”
    when
    MARC.”245″ has any “a,b”
    then
    create pnx.”display”.”lds05″ with MARC.”200″ subfields “a,b”

    200 should be 245

  10. Hi

    Just to add:

    rule “Primo VE Marc – Lsr01”
    when
    MARC.”300” has any “a,b”
    then
    create pnx.”search”.”lsr01″ with MARC “300” subfields “a,b”
    end

    This concatenates the subfields for search.
    I’m just adding this here because I was looking for an example (to eliminate false positives in local search fields) and didn’t realize this already covers it.

  11. Hi Israel,

    You can use the following line in the format rule:

    append TEMP”1″ to pnx.”display”.”format” delimited by “-”

    This line is instead of the create action:

    rule “Primo VE – Format 347”
    when
    MARC is “347”
    then
    set TEMP”1″ to MARC.”347″ excluding num subfields without sort
    append TEMP”1″ to pnx.”display”.”format” delimited by “-”
    end

    If you would like to concatenate all the format fields (300, 346, 347 etc.) you should add the ‘ append’ action for all the format rules

    Thank you for raising this question.

    Regards,
    Moran

  12. Is there a way to access the values of the 007 control field?

    This rule:

    rule “Primo VE – Lds48”
    when
    MARC.control.”007″(0-1) equals “vd”
    then
    create pnx.”display”.”Lds48″ with “TEST”
    end

    results in this error:

    [3] Unable to expand: MARC.control.”007″(0-1) equals “vd” [3175,17]: [ERR 102] Line 3175:17 mismatched input ‘”007″‘ expecting ‘identifier’ in rule

  13. Hello,

    Thank you for raising this question.
    The example you used is working for 008 – we developed it specific for the 008 for customers needs.

    Since using it for 007 required a new development please raise it as enhancement request

    Thank you,
    Moran

  14. I want to concatenate 5 different 5XX fields if they exist. So I think my When statement would be something like:

    MARC is “500”.”a” OR MARC.”518″ has any “a,d,p” OR MARC is “540”.”a” OR MARC.”546″ has any “a,b” OR MARC is “504”.”a”

    If this is correct, do I then just set each different 5XX field to a TEMP field and then concatenate them all together with a delimiter at the end. Does it handle everything ok if the 5XX field doesn’t exist?

  15. That first example to create a hypertext link out only seems to produce an error when attempting to adapt it for 555 subfield u,z (u is the URL, z is the text that should appear). Suggestions? Thanks!

  16. Iowa State University Library 01IASU_INST,

    Apologizes for the late response.
    When using OR in the condition section – you must mention only one field (and if needed subfields). The reason is that the system can only get one field to compare the fields in the action section.
    When using more than one field with OR in the condition – the code will not know for sure to which field it should refer – Thank you for raising this question since this is an important note that will be added to the documentation.

    In order to make a rule that will find the 5xx fields you want, you can use the following syntax:

    rule “Primo VE – Lds15”
    when
    MARC is “500”.”a”
    then
    create pnx.”display”.”lds15″ with MARC.”500″.”a”
    end

    rule “Primo VE – Lds151”
    when
    MARC is “504”.”a”
    then
    create pnx.”display”.”lds15″ with MARC.”504″.”a”
    end

    rule “Primo VE – Lds152″
    when
    MARC.”518” has any “a,d,p”
    then
    create pnx.”display”.”lds15″ with MARC.”518″ subfields “a,d,p”
    end

    rule “Primo VE – Lds153”
    when
    MARC is “540”.”a”
    then
    create pnx.”display”.”lds15″ with MARC.”540″.”a”
    end

    rule “Primo VE – Lds154″
    when
    MARC.”546” has any “a,b”
    then
    create pnx.”display”.”lds15″ with MARC.”546″ subfields “a,b”
    end

    With this syntax it will get the 5xx that exist in the source.

    Thanks,
    Moran

Leave a Reply