Skip to main content
ExLibris
  • Subscribe by RSS
  • Ex Libris Knowledge Center

    Configuring Normalization Rules for Display and Local Fields

    Last updated: March 19, 2024

    Return to menu

    This page is specific to Primo VE environments. For Primo customers, see Working with Normalization Rules and Mapping to the Normalized Record.

    Introduction

    Normalization rules provide the building blocks for controlling and making changes to the way metadata in bibliographic records is seen by patrons. Primo VE enables you to modify the normalization rules for the out-of-the-box display fields (such as Title or Contributor). You can also create normalization rules for local display fields so that you can control the display of additional metadata in the record that is not mapped to one of the out-of-the-box display fields. Applied changes are immediately available for discovery in Primo VE. For information on how to create display and local fields, see Configuring Local Display and Search Fields for Primo VE.

    This page describes the syntax used to create the normalization rules, which are defined with Drools tools. We recommend starting with an existing rule that is similar to the rule that you are looking to define and modify it as needed. For additional examples to start with, see Normalization Rules Examples.

    • The term MARC on this page refers to the following supported formats in Primo VE: MARC21, UNIMARC, KORMARC, and CNMARC.

    • Ensure that you use the quotation mark character (u+0022) as specified for the various elements of the normalization rules.

    Primo VE Administration Certification - Local Fields (11 min)

    Normalization Rule Syntax

    Each display and local field can contain one or more rules that contain a set of conditions and a set of actions that are applied to records when all conditions are met for the rule. Each action within a rule can be performed on a single field, and it is performed in the order in which it appears in the rule.

    When applying multiple rules to a display or local field, you may want to specify a priority (the default is 0 if not specified) to each rule. Actions stipulated in the rule with the higher priority value are performed first. For example, the actions in a rule with priority 2 are performed before the actions in a rule with priority 1. Assigning a priority is only necessary when the rules apply actions to the same field, and they must be done in a specific sequence. If no priority is assigned to the rules, the rules are processed from top to bottom.

    rule "title"

         priority <rule with highest number receives priority>

         when

              Condition1 <Boolean operator>

              Condition2 <Boolean operator>

                 ...

              Condition(n)

         then

              Action1

                 ...

              Action(n)

    end

    • When a display or local field's mapping contains more than one rule stanza, the title for each rule must be unique. For example:

      rule "Primo VE Display - contributor 700"
      rule "Primo VE Display - contributor 700/2"
    • For local fields, the title of the first rule must use the following format based on whether the local field is used for display (Lds) or search/facets (Lsr):

      rule "Primo VE - <display_or_search><local field number>"

      For example, if you are creating a rule for local display field 100, you must use the following title:

      rule "Primo VE - Lds100"
    • The when, then, and end statements must be on their own line.

    • Each rule must be closed with an end statement.

    • Boolean operators are permitted within the when clause only.

    • While it is permissible to include multiple Boolean operators in the rules, slower performance is likely to result when a large number of Boolean operators are specified. Thus, each rule should not include more than 200 Boolean operators.

    Conditions

    The when clause contains one or more conditions (separated by Boolean operators) that must be met by the metadata in the record before executing one or more actions, which are defined in the then clause. Priority can be given to groups of conditions by enclosing them in parentheses (see Grouping Conditions). See Java Routines to see which of the routines can be used in when clauses.

    For example:

    # An example of a "when" condition clause.

     

    when

         MARC is "502"."a"

     

    ----------------------

     

    # An example of a "when" condition clause with Boolean operators and a group.

     

    when

         MARC."502" has any "a,b,c" AND

         (MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" OR

         MARC."502"."a" match ".*" AND MARC."502"."c" match ".*")

     

    When creating a set of conditions for a rule:

    • If you need to write or check MARC fields in the when and then clauses, ensure that you check for their existence before using them. See Existence Checks for more details.

    • If you need to refer to specific subfields in the when and then clauses, ensure that you check for their existence before using them.

    • After you have checked for a field's or subfield's existence, you can add comparison checks to compare information in the subfields. See Comparison Checks for more details.

    • Do not place comparison checks on the same line as existence checks. Start the comparison checks on the line after an existence check.

    • Ensure that all sets of conditions contain an existence check. For example, if a set of conditions on both sides of an OR operator provides stand-alone conditions, each side must include an existence check. For more information, see the OR Operator.

    You are not permitted to check for a field's or subfield's existence more than once. By checking for a subfield's existence, you are also checking for the field's existence.

    The following table describes the syntax for the possible MARC conditions:

    MARC Conditions
    Condition Example
    Existence Checks:

    is – Checks for the existence of the specified field and a subfield if specified. Valid formats:

    • DCMI is "dcterms"."field"
    • DCMI is "dc"."field"
    • MARC is "<field>"
    • MARC is "<field>"."<subfield>"
    • MARC.control is "<control number_or_LDR>"

    If you have checked for the existence of a MARC field (with or without specific subfields) using either a has any or is check on the left side of the AND NOT operation, and you want to check for the nonexistence of another MARC field that has one or more specific subfields, you must use the has any check on the right side of the AND NOT operation. For example:


    MARC is "502"."a,b,c" AND NOT MARC."505" has any "a"

    # The DCMI field exists.

    DCMI is "dc"."coverage"
    DCMI is "dcterms"."coverage"

    # The MARC 880 field exists.

    MARC is "880"

    # The MARC 260 field exists and has subfield c.

    MARC is "260"."c"

    # The MARC control field 001 exists.

    MARC.control is "001"

    # The MARC Leader exists.

    MARC.control is "LDR"

    has any – Checks for the existence of the specified field and any of its listed subfields. Valid format (MARC only):

    MARC."<field>" has any "<subfield list>"

    # The 700 field exists and has one or more of the following subfields: a, b, c, d, e, j, q, and u.

    MARC."700" has any "a,b,c,d,e,j,q,u"

    # The 700 field exists and has any of the following subfields: a, b, c, f, g, or h.

    MARC."700" has any "a-c,f-h"
    Combined Existence and Comparison Checks:

    matches (Leader check) – Checks for the existence of the Leader field and uses a regular expression to match information anywhere in the specified position in the Leader. Valid format:

    MARC.control."LDR"(start_position-end_position) matches "<Java_regex>"

    # Checks for existence of the Leader field and makes sure that the first character from the left is a number:

    MARC.control."LDR"(0-1) matches "0-9"

    # Checks for existence of the Leader field and makes sure that the two characters in positions 6 and 7 are any of the specified pairs of characters:

    MARC.control."LDR"(6-8) matches "ab|ai|as"

    equals (Leader check) – Checks for the existence of the Leader field and ensures that the entire content between the specified start and end position in the Leader equals the specified value. Valid format:

    MARC.control."LDR"(start_position-end_position) equals "<value>"

    # Checks for existence of the Leader field and ensure that the first character from the left is equal to 0:

    MARC.control."LDR"(0-1) equals "0"

    does not equal – Checks for the existence of the Leader field and ensures that the entire content between the specified start and end position in the Leader does not equal the specified value. Valid format:

    MARC.control."LDR"(start_position-end_position) does not equal "<value>"

    # Checks for existence of the Leader field and makes sure that the first character from the left is not equal to 0:

    MARC.control."LDR"(0-1) does not equal "0"

    Comparison Checks:

    match – After checking for existence of a field first, this operation enables you to use a regular expression to match specific information in a subfield. Valid format:

    MARC."<field>"."<subfield>" match "<Java_regex>"

    # The 880 field has a subfield 6 that matches the expression 505-.*. The .* portion of the expression means that it accepts anything after the string.

    MARC."880"."6" match "505-.*"

    # The 562 field has a subfield 5 that matches a specific library code (such as MAIN).

    MARC."562"."5" match "MAIN"

    equals (indicator check) – After checking for existence of a field first, this operation enables you to match the contents of the specified indicator and its value. Valid formats:

    MARC."<field>".ind"<indicator>" equals "<value>"

    # The MARC 260 field's first indicator is a 3.

    MARC."260".ind"1" equals "3"

    Using Boolean Operators in the When Clause

    Boolean operators enable you to combine conditions to create more complex filters that determine whether a field or subfield matches the necessary requirements to either write or modify its contents in the then clause (see Actions). In general, a series of the same Boolean operations are evaluated from left to right, but the following precedence is given if the Boolean operations are mixed:

    1. AND NOT

    2. AND

    3. OR

    You can override precedence by enclosing groups of conditions with parentheses. For more information, see Grouping Conditions.

    AND Operator

    This Boolean operator indicates that the next condition must be true. It cannot be used between two existence checks for the same field, but it can be used to add a subfield comparison for the same field or to check the existence of another field:

    This rule checks for the existence of both the MARC 502 field with any of the a, b, and c subfields and the MARC 505 fields with the 'b' subfield.

     

    rule "Primo VE - Lds05"

         when

              MARC."502" has any "a,b,c" AND MARC is "505"."d"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # FAILS - This rule attempts to check for the existence of the MARC 502 field and the 'd' subfield and any of the a, b, and c subfields. Since the existence of the 502 field is checked twice, it will fail compilation. 

     

    rule "Primo VE - Lds05"

         when

              MARC."502" has any "a,b,c" AND MARC is "502"."d"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # This rule checks for the existence of the MARC 502 field and the 'd' subfield and any of the a, b, and c subfields. The existence of the MARC 502 field is checked only once. Comparison checks are made on the specific subfields whose existence was checked only once.

     

    rule "Primo VE - Lds05"

         when

              MARC."502" has any "a,b,c,d" AND

              (MARC."502"."a" match ".*" OR MARC."502"."b" match ".*" OR MARC."502"."c" match ".*") AND

              MARC."502"."d" match ".*"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

    AND NOT Operator

    This Boolean operator indicates that the next condition must not be true. It cannot be used between two existence checks for the same field, but it can be used to add a subfield comparison for the same field or to check the existence of another field:

    This rule checks for the existence of the MARC 502 field and the nonexistence of the MARC 505 field.

     

    rule "Primo VE - Lds05"

         when

              MARC is "502"."a" AND NOT MARC."505" has any "a"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    -----------------------

     

    # FAILS - This rule attempts to find records that have a nonempty 502 'a' subfield and an empty 'b' subfield. Since this rule attempts to check for the existence and nonexistence of the MARC 502 field, it will fail compilation.

     

    rule "Primo VE - Lds05"

         when

              MARC is "502"."a" AND NOT MARC."502" has any "b"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    -----------------------

     

    # This rule finds records that have a nonempty 502 'a' subfield and an empty 'b' subfield.

     

    rule "Primo VE - Lds05"

         when

              MARC."502" has any "a,b"

              MARC."502"."a" match ".*" AND NOT MARC."502"."b" match ".*"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

    OR Operator

    This Boolean operator indicates that the next condition may or may not be true. When using this operator to link a series of Comparison Checks, it is necessary to ensure that the set of conditions on both the left and right side of the OR operator contain an existence check. It may be necessary to group conditions together to ensure that comparison checks are not treated as stand-alone conditions by the Drools compiler.

    This rule checks for the existence of either the MARC 502 field and a, b, or c subfields or the MARC 502 field and 'd' subfield. This passes because existence checks were placed on both sides of the OR operator.

     

    rule "Primo VE - Lds05"

         when

              MARC."502" has any "a,b,c" OR MARC is "502"."d"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # This rule checks for the existence of a 502 field and makes sure that either subfields a, b, and c are not empty or subfields d is not empty.

     

    rule "Primo VE - Lds05"

         when

              MARC is "502" AND
              (MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" AND
               MARC."502"."c" match ".*" OR MARC."502"."d" match ".*")

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # This rule checks for the existence of a 502 field and makes sure that subfields a and b and c are not empty and either subfield c or d is not empty.

     

    rule "Primo VE - Lds05"

         when

              MARC is "502" AND
              MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" AND
              (MARC."502"."c" match ".*" OR MARC."502"."d" match ".*")

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # FAILS - This rule fails compilation because the set of conditions on the right side of the OR operator do not contain an existence check.

     

    rule "Primo VE - Lds05"

         when

              (MARC is "502" AND
              MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" AND
              MARC."502"."c" match ".*") OR MARC."502"."d" match ".*"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    ----------------------

     

    # FAILS - This is treated the same as the previous example.

     

    rule "Primo VE - Lds05"

         when

              MARC is "502" AND
              MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" AND
              MARC."502"."c" match ".*" OR MARC."502"."d" match ".*"

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

    ----------------------

     

    # This rule checks for the existence of a 502 field and makes sure that either subfields a and b and c are not empty or subfield d is not empty.

     

    rule "Primo VE - Lds05"

         when

              (MARC is "502" AND
              (MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" AND
              MARC."502"."c" match ".*") OR MARC."502"."d" match ".*")

         then

              create pnx."display"."lds05" with MARC "502" subfields

    end

     

    Grouping Conditions

    If you want to override the precedence of the Boolean operations, you can group conditions to be processed together by enclosing them with parentheses. When groups are nested, the inner most groups are processed first. Groups and conditions within each group will continue to use Boolean operator precedence (see Using Boolean Operators in the When Clause).

    For example:

    # The following series of conditions passes when the MARC field exists and either subfields a and b are not empty or subfields c and d are not empty:

     

    rule "Primo VE - Lds05"

         when

              MARC is "502" AND

              (MARC."502"."a" match ".*" AND MARC."502"."b" match ".*" OR MARC."502"."c" match ".*" AND MARC."502"."d" match ".*")

     

    ----------------------

     

    # With parentheses, the same series of conditions passes when the MARC field exists and either subfields a,b, and d are not empty or subfields a,c, and d are not empty:

     

    rule "Primo VE - Lds05"

         when

              

              MARC is "502" AND

              (MARC."502"."a" match ".*" AND (MARC."502"."b" match ".*" OR MARC."502"."c" match ".*") AND MARC."502"."d" match ".*")

     

    When grouping conditions, you must ensure that all conditional outcomes include existence checks. For more information, see OR Operator.

    Actions

    The then clause enables you to apply actions to a single field in a record based on conditions specified in the rule. If all the conditions are met, the actions are applied to the record in the order in which they are listed. The actions are executed from top to bottom.

    For example:

    # A simple "then" clause that writes all subfields from a MARC field to an out-of-the-box display field.

     

    then

         create pnx."display"."alternate_contributor" with MARC."880" subfields

    end

    In addition, you can use any of the predefined Java routines as actions in the then clause. For more information, see Java Routines.

    Boolean operators are not permitted between actions.

    The following table describes the syntax for the possible MARC actions.

    MARC Actions
    Action Examples
    Assignment Actions: Enable you to save information from a MARC field to a display/search field or to a temporary field (TEMP"i"). 

    set – This action changes the contents of an existing field. If a field does not exist, the field is created. Valid format:

    set <field> to <field>

    set pnx."display"."contents" to TEMP"1"

    set TEMP"1" to pnx."display"."contents"

    set TEMP"1" to DCMI."dcterms"."format"

    create – This action creates a display field and sets its contents to the value of a specified field. If a display field already exists, an additional field is added. Format:

    create <display field> with <field>

    create pnx."display"."contents" with MARC "505"."a"

    create operational."prima_display"."coverage" with DCMI."dcterms"."coverage"

    Subfield Actions: Enable you to include/exclude a MARC field's subfields during the assignment of a MARC field to a display/search field or to a temporary field (TEMP"i").

    excluding num subfields without sort – This action uses only the non-numeric subfields and puts them in the order that they appear in the MARC record. Valid format:

    excluding num subfields without sort

    create pnx."display"."contents" with MARC "505" excluding num subfields without sort

    excluding subfields without sorting – This action excludes all specified subfields and puts the remaining subfields in the order that they appear in the MARC record. Valid format:

    excluding subfields without sorting "<subfield list>"

    In the <subfield list>:

    • A hyphen (-) may be used to specify a range of subfields.

    • Subfield and subfield ranges may be delimited by the following characters: comma, pipe (|), or a space.

    create pnx."display"."contents" with MARC "505" excluding subfields without sorting "a-c"

    Subfield list examples:

    • "a-d"
    • "a b c d"
    • "a|b|c|d"
    • "a,b,c,d"
    • "a-c,d"

    subfields – This action uses either all subfields or only the specified subfields and sorts them by the subfield letter/number, not the order in which they appear in the MARC record. Format:

    subfields "<subfield list>"

    You can pair the delimited by and remove substring using regex options together to remove the characters that match the specified regular expression and to place the specified delimiter between all specified subfields:

    subfields "<subfield list>" delimited by "<string>" remove substring using regex "<Java_regex>"

    The delimited by and remove substring using regex options cannot be used separately with the subfields action. 

    create pnx."display"."contents" with MARC "505" subfields

    create pnx."display"."contents" with MARC "505" subfields "a-c"

     

    create pnx."display"."contents" with MARC "505" subfields "a-c" delimited by "--" remove substring using regex "\\.+$"

    sub without sort – This action uses the specified subfields and puts them in the order that they appear in the MARC record. Valid format:

    sub without sort "<subfield list>"

    The delimited by option allows you to place a delimiter between the specified subfields.

    sub without sort "<subfield list>" delimited by "<string>"

    When the wrap fields option is used in conjunction with the replace wrapping delimiters transformation action, you can prefix and append delimiters to each subfield specified in the list:

    sub without sort "<subfield list>" wrap subfields

    Because the wrap subfields action adds a placeholder before and after each subfield in the list, a subfield's placeholders appear in the output if they are not replaced with a corresponding replace wrapping delimiters action.

    set TEMP"1" to MARC."710" sub without sort "a,b,c,d,e"

     

    set TEMP"1" to MARC."710" sub without sort "a,b,c,d,e" delimited by " "

     

    set TEMP"1" to MARC."200" sub without sort "a,b,c,d,e,f,g,h,i,v" wrap subfields

    Transformation Actions: Enable you to search and modify data from a field. 

    remove substring using regex – This action removes a substring from the contents of a temporary field using a specified regular expression. Valid format:

    remove substring using regexp (TEMP"<index>","<Java_regex >")

    If this action is applied to a subfield that does not exist, the display or local field may not be created or may be incomplete.

    remove substring using regex (TEMP"1","(/|:|;|=|,)+$")

    concatenate with delimiter – This action concatenates the contents of two temporary fields and separates them with a delimiter. The result is placed in the first temporary field. Format:

    concatenate with delimiter (TEMP"<index>",TEMP"<index>","<delimiter>")

    concatenate with delimiter (TEMP"1",TEMP"2","")

    add prefix – This action adds the specified value to the beginning of the temporary field. Valid format:

    add prefix (TEMP"<index>","<value>")

    add prefix (TEMP"2","$$Q")

    add suffix – This action adds the specified value to the end of the temporary field. Valid format:

    add suffix (TEMP"<index>","<value>")

    add suffix (TEMP"2","$$Q")

    replace string by string – This action replaces all occurrences of a regular expression with a specified value. Valid format:

    replace string by string (TEMP"<index>","<Java_regex>","<string>")

    replace string by string (TEMP"1","[^0-9]","\\?")

    replace wrapping delimiters – This action is used in conjunction with the wrap subfields subfield action, and it enables you to place a specified delimiter before and after a specified subfield. Valid format:

    replace wrapping delimiters (TEMP"<index>","<subfield>","<prefix_delimiter>","<suffix_delimiter>")

    For more examples, see the out-of-the-box UNIMARC normalization rules for the Title and Publisher display fields.

    set TEMP"1" to MARC."200" sub without sort "a,b,c,d,e,f,g,h,i,v" wrap subfields

    replace wrapping delimiters (TEMP"1","a"," ; ","")

    replace wrapping delimiters (TEMP"1","b"," [","]")

    return list using regex – This action searches for all occurrences of a regular expression in the second temporary field and copies them as a list to the first temporary field. Valid format:

    return list using regex (TEMP"<index>",TEMP"<index>","<Java_regex>")

    return list using regex (TEMP"1",TEMP"2","[a-z]{3}")

    remove string – This action removes a specified string from a temporary field. Valid format:

    remove string (TEMP"<index>","<value>")

    remove string (TEMP"1","<<")

    remove leading and trailing spaces – This action removes beginning and trailing spaces in a temporary field. Valid format:

    remove leading and trailing spaces (TEMP"<index>")

    remove leading and trailing spaces (TEMP"1")

    replace spaces – This action replaces all spaces in a temporary field with a specified character or string. Valid format:

    replace spaces (TEMP"<index>","<string>")

    replace spaces (TEMP"1"," ")

    lower case – This action changes all letters in a temporary field to lowercase. Valid format:

    lower case (TEMP"<index>")

    lower case (TEMP"1")

    multilingual – When added to the normalizations rules for the Subject, Creator, or Contributor display fields, the system utilizes the Multi-Lingual Configuration mapping table to display entries that are specific to the display language selected in Primo VE. For more details, see Multi-Lingual Configuration in Primo VE. Valid format:

    multilingual by "MARC_field" "Display_Field" "display"

    Out-of-the-box, multilingual transformation is enabled in the normalization rules. If it is omitted, all entries for the display field appear in the facets and record details regardless of the display language setting in Primo VE.

    rule "Primo VE Display- Subject 650"
        when
            MARC is "650"."a"
        then
            set TEMP"1" to MARC."650"."a"
            set TEMP"3" to multilingual by "650" "Subject" "display"
            concatenate with delimiter (TEMP"1",TEMP"3","") 
            create pnx."display"."subject" with TEMP"1"
    end

    Tips for Actions

    The following tips may be helpful when creating actions:

    • You can use Assignment Actions to save information to TEMP"i" variables (such as TEMP"1") for later use in the processing of the then clause. After you have saved information to a TEMP"i", you can overwrite its contents with Transformation Actions, overwrite an existing MARC field in the record, or add an additional MARC field to the record. For example:

      # Saves the contents of subfield a to the TEMP"2" variable for later use.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"."a"

           then

                set TEMP"2" to MARC."502"."a"

                ...

      end

       
    • When saving information from a MARC field, you must specify a subfield or use one of the Subfield Actions.

      # Saves only MARC 502 subfield 'a' to Local Display Field 5 if subfield 'a' exists. If a record has multiple 502 fields, the local display field will be overwritten as each 502 field is processed.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"."a"

           then

                set pnx."display"."lds05" to MARC."502"."a"

      end

       

      ----------------------

       

      # Saves all MARC 502 subfields to Local Display Field 5 if it exists. The create action allows you to create multiple display fields for the MARC field. A new local display field is created in the record as each 502 field is processed.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"

           then

                create pnx."display"."lds05" with MARC."502" subfields

      end

       

      ----------------------

       

      # Fails - Attempts to save the MARC 502 subfield to Local Display Field 5 if it exists. This fails compilation since a subfield action was not included with the create statement.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"

           then

                create pnx."display"."lds05" with MARC."502"

      end

       

       
    • If you need to save a value from a specific subfield, you must add a condition to the when clause that checks for that subfield's existence. For more details, see Existence Checks. For example:

      # Checks for the existence of a MARC 502 field that specifically has subfield a and writes only subfield a.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"."a"

           then

                create pnx."display"."lds05" with MARC."502"."a"

      end

       

      ----------------------

       

      # Checks for the existence of a MARC 502 field that has either subfield a or b and writes any existing subfield. When using the "has any" condition, make sure that you do not write any subfields that do not exist. This can be accomplished by adding a comparison check to see that a specific field is not empty.

       

      rule "Primo VE - Lds05"

           when

                MARC."502" has any "a,b"

           then

                create pnx."display"."lds05" with MARC."502" subfields

      end

       

      ----------------------

       

      # FAILS - Attempts to write a specific subfield for which its existence had not been checked.

       

      rule "Primo VE - Lds05"

           when

                MARC is "502"

           then

                create pnx."display"."lds05" with MARC."502"."a"

      end

       

      ----------------------

       

      # FAILS - Attempts to write a specific subfield for which its existence had not been checked. Subfield a was tested to see if it had a value, but its existence was not specifically checked.

       

      rule "Primo VE - Lds05" 

           when
                 MARC is "502" AND MARC."502"."a" match ".*"
           then
                 create pnx."display"."lds05" with MARC."502"."a"
      end

    Java Routines

    The following table lists additional Java routines that are typically added as actions to perform a series of actions with a single command.

    Java Routines
    Routine Description

    normalize discovery lang (TEMP"<index>")

    Check to see that the language is valid. If it is less than three letters or not defined in the ISO 639-2 language list , it is set to ‘und’ - undefined.

    If you add languages to the Customized Languages Codes code table, you should not use this routine.

    kormarc remove nonfiling brackets MARC."{tag}" sourcetag "{fieldTag}" from TEMP"{i}"

    Relevant only for KORMARC formats.

    If

    ("{fieldTag}" is equal to 630|740 AND MARC."{tag}" has first indicator 1)
    OR
    ("{fieldTag}" is equal to 130|222|240|242|243|245|440|490|730|830 AND MARC."{tag}" has second indicator 1)

    Then

    The routine removes the surrounding round brackets from TEMP"{i}" if they exist.

    Example:

    kormarc remove nonfiling brackets MARC."630" sourcetag "630" from TEMP"1"

    Date1

    Position 7-11 in the MARC 008 field. For example:

    set TEMP"1" to MARC.control."008".Date1

    Date2

    Position 11-15 in the MARC 008 field. 

    For example:

    set TEMP"1" to MARC.control."008".Date2

    Language

    Position 35-37 in the MARC 008 field. 

    For example:

    set TEMP"1" to MARC.control."008".Language

    prima display title

    This action retrieves the title from the MARC record and can be used in conjunction with the MARCRECORD routine. For example:

    when
         MARCRECORD
    then
         set TEMP"1" to prima display title

    For more details on the mapping used for the Title field, see MARC Display Section Mapping.

    MARCRECORD

    When placed in the when clause, this routine checks for the existence of the necessary MARC title fields. All of the following must be true to satisfy the condition:

    1. Check to see if the LDR field exists in the MARC.

    2. If yes, check to see if there is a in position 6 and b, i, or s in position 7.

    3. If those are true, then the records is a journal and the title is taken from field 130 subfields a,d,f,k,l,m,n,o,p,r,s.

    4. If there is no LDR field, check the title in field 245 subfields a,b,f,g,k,n,p,s.

    For more information, see the prima display title routine.

    Inserting Subfield Delimiters into the PNX Records

    Some fields in the PNX record have multiple values that are delimited by two dollar signs followed by a specific character or number (similar to MARC subfields). The following table lists the various subfield delimiter types used in the PNX record. 

    The following table lists the various subfield delimiter types used in the PNX record.

    Subfield Delimiter Types
    Delimiter Description

    C

    A constant that displays before the field. This delimiter can be used only in the Display section for the following fields: identifier, relation, and description.

    The constant can be a code (lowercase with no spaces or special characters except for underscores). The code is translated to a name for display in the Front End using the Display Constants Labels code table (Configuration Menu > Discovery > Display Configuration > Labels). If the text added has no translation in the code table, it appears as entered in the rules. For more details, see Configuring Display Labels for Primo VE.

    Q

    Contains the linking portion of the display field for enhanced hypertext linking. Otherwise, linking is performed on the display portion of the display field. For more information, see Configuring Hypertext Link Definitions for Primo VE.

     

    V

    Value of the field (to distinguish between the value of the field and the display text or constant).

    Z

    Linked related record identifier.

    The following normalization rules insert an ISBN constant before the value of the subfield in the PNX record. In addition, the $$C subfield delimiter inserts a space, a colon, and another space between the constant and the record's identifier—for example, ISBN : 1-4963-0062-9). 
    rule "Primo VE - Identifier 020"
        when
            MARC is "020"."a"
        then
            set TEMP"1" to MARC "020"."a"
            add prefix (TEMP"1","$$CISBN$$V")
            create pnx."display"."identifier" with TEMP"1"
    end
     
    rule "Prima Display - ISBN 776"
        when
            MARC is "776"."z"
        then
            set TEMP"1" to MARC "776"."z"
            add prefix (TEMP"1","$$CISBN$$V")
            create pnx."display"."identifier" with TEMP"1"
    end
    Inserting HTML into PNX Records

    Inserting HTML Tags into PNX Records

    Primo VE enables you to include HTML tags in the normalization rules so that you can apply HTML styles and formatting to search results. The following HTML tags are supported:
    Supported HTML Tags
    span
    table
    tbody
    th
    tr
    td
    a
    s
    b
    br
    i
    u
    p
    img
    !--
    style
    The following normalization rules apply bold to the ISBN constant and inserts it before the value of the subfield in the PNX record. In addition, the $$C subfield delimiter inserts a space, a colon, and another space between the constant and the record's identifier—for example, ISBN : 1-4963-0062-9). 
    rule "Primo VE - Identifier 020"
        when
            MARC is "020"."a"
        then
            set TEMP"1" to MARC "020"."a"
            add prefix (TEMP"1","$$C<b>ISBN</b>$$V")
            create pnx."display"."identifier" with TEMP"1"
    end
     
    rule "Prima Display - ISBN 776"
        when
            MARC is "776"."z"
        then
            set TEMP"1" to MARC "776"."z"
            add prefix (TEMP"1","$$C<b>ISBN</b>$$V")
            create pnx."display"."identifier" with TEMP"1"
    end
    Inserting HTML into PNX Records

    Normalization Rule Examples

    This section provides a few basic examples of normalization rules for Primo VE.

    For more advanced examples, see the Primo VE Normalization Rules Examples page on the Ex Libris Developer Network.

    Viewing the Default Rules

    In addition to the examples in the following sections and the Ex Libris Developer Network, you can view the out-of-the-box rules for each Display field before making any changes to them.

    To view a Display field's default rules:
    1. On the Display Fields page (Configuration Menu > Discovery > Display Configuration > Manage Display Fields), select Add display field from the Add field drop-down list to open the Define a Display Field page.

    2. Select an out-of-the-box display field from the Field to edit drop-down list.

    3. Depending on your supported formats, edit the normalization rule row for the display field (for example, Marc21 Normalization Rule for display.)

      PVE_DF_NormRule.png

      Out-of-the-Box MARC Normalization Rule for Edition Field
    4. If you have already modified a field's rules, you can copy and save your rule modifications to the side, and then select Restore Defaults to see the default rules.

    MARC Examples

    Excluding Numbered Subfields

    When a MARC 880 $$6 subfield contains the string 520-<any_value>, the following rule will display the contents of all non-numeric subfields in the Description display field without sorting them:

    rule "Primo VE - Description 880"

    when
    MARC is "880" AND
    MARC."880"."6" match "520-.*"
    then
    create pnx."display"."description" with MARC."880" excluding num subfields without sort

    end

     
    MARC 880 Rule - Create Description Display Field

    Using Concatenation

    When a MARC 600 field contains any of the subfields a-u, w-z and its second indicator is not 2, the rule below will display the concatenation of the following strings separated by " -- " in the Subject display field:

    • A string that has no period at the end and contains the values from subfields a-u, and w (which are separated by a space).

    • A string that has no period at the end and contains the values from subfields x-z (which are separated by " -- ").

    rule "Primo VE - Subject 600"

    when
    MARC."600" has any "a-u,w-z" AND NOT
    MARC."600".ind"2"  equals "2"
    then
    set TEMP"1" to MARC."600" subfields "a-u,w" delimited by " " remove substring using regex "\\.+$"
    set TEMP"2" to MARC."600" subfields "x-z" delimited by " -- " remove substring using regex "\\.+$"
    concatenate with delimiter (TEMP"1",TEMP"2"," -- ")
    create pnx."display"."subject" with TEMP"1"

    end

     
    MARC 600 Rule - Create Subject Display Field

    Using the Language Normalization Routine

    When a MARC 041 $$a exists, the following actions from the rule below are applied to the field to create the Language display field:

    1. The contents of MARC 041 $a is copied to Temp2, and all letters are converted to lowercase.

    2. All three-letter language codes in Temp2 are stored as a list in Temp1.

    3. If the language codes stored in Temp1 are valid, the Language display field is created.

    rule "Primo VE - Language 041 a"

    when
    MARC is "041"."a"
    then
    set TEMP"2" to MARC."041"."a"
    lower case (TEMP"2")
    return list using regex (TEMP"1",TEMP"2","[a-z]{3}")
    normalize discovery lang (TEMP"1")
    create pnx."display"."language" with list TEMP"1"

    end

     
    MARC 041 a Rule - Create Language Display Field

    Adding Search and Facet Rules

    The following rule creates local field Lsr14 with the values from the MARC 700 a subfield (Added Entry-Personal Name; $a- Personal name).

    Rules used for local search and facet fields must be saved to the local search field (for example, "search"."lsr14") instead of the local display field (for example, "display"."lds14").

    rule "Primo VE Marc - Lsr14"

    when
    MARC is "700"."a"
    then
    create pnx."search"."lsr14" with MARC "700"."a"
    end
     
    MARC 700 Rule - Create Local Search and Facet Field

    MARC Source:

    700    1#$aMelville, Gert, $eeditor.

    700    1#$aRuta, Carlos, $eeditor.

    700    1#$aCarugati, Laura S, $eeditor.

    Primo VE Output:

    PVE_LocalSearchFieldExampleOutput.png

    Dublin Core Examples

    The syntax that is used for the DC normalization rules is similar to what is used for MARC normalization rules, but instead of using the MARC keyword, the DCMI keyword is used. Unless a command appears to be MARC-specific, you can use the same routines for both MARC and DC formats.

    It is recommended that you use the templates provided for the DC fields as a guide and pay close attention to where you must store the information for each DC field (such as operational."prima_display"."creator" for the Creator field).

    Creator Display Field

    The following example shows the default normalization rules used to display the Creator field:

    rule "prima_display creator- dcterms:creator"
                    when
                                    DCMI is "dcterms"."creator"
                    then
                                    create operational."prima_display"."creator" with DCMI."dcterms"."creator"
    end

    rule "prima_display creator - dc:creator"
                    when
                                    DCMI is "dc"."creator"
                    then
                                    create operational."prima_display"."creator" with DCMI."dc"."creator"
    end

     
    Default Creator Display Field Rules

    Coverage Display Field

    The following example shows the default normalization rules used to display the Coverage field:

    rule "prima_display coverage - dc:coverage"
        when
            DCMI is "dc"."coverage"
        then
            create operational."prima_display"."coverage" with DCMI."dc"."coverage"
    end

    rule "prima_display coverage - dcterms:coverage"
        when
            DCMI is "dcterms"."coverage"
        then
            create operational."prima_display"."coverage" with DCMI."dcterms"."coverage"
    end

    rule "prima_display coverage - dcterms:spatial"
        when
            DCMI is "dcterms"."spatial"
        then
            create operational."prima_display"."coverage" with DCMI."dcterms"."spatial"
    end

    rule "prima_display coverage - dcterms:temporal"
        when
            DCMI is "dcterms"."temporal"
        then
            create operational."prima_display"."coverage" with DCMI."dcterms"."temporal"
    end

    Default Coverage Display Field Rules

    Format Display Field

    For the Format field, the following example shows the usage for the add prefix command and the TEMP"1" variable:

    rule "prima_display format - dcterms:format"
        when
            DCMI is "dcterms"."format"
        then
            set TEMP"1" to DCMI."dcterms"."format"
            add prefix (TEMP"1","000 ")
            create operational."prima_display"."format" with TEMP"1"
    end

    rule "prima_display format - dc:format"
        when
            DCMI is "dc"."format"
        then
            set TEMP"1" to DCMI."dc"."format"
            add prefix (TEMP"1","000 ")
            create operational."prima_display"."format" with TEMP"1"
    end

    rule "prima_display format - dcterms:extent"
        when
            DCMI is "dcterms"."extent"
        then
            set TEMP"1" to DCMI."dcterms"."extent"
            add prefix (TEMP"1","000 ")
            create operational."prima_display"."format" with TEMP"1"
    end

    rule "prima_display format - dcterms:medium"
        when
            DCMI is "dcterms"."medium"
        then
            create operational."prima_display"."format" with DCMI."dcterms"."medium"
    end

     
    Default Format Display Field Rules