Conversion rules for generating MARC fields are specified in a simple but flexible XML format, with elements in the namespace http://www.loc.gov/bf2marc. The conversion rules are used by the compile.xsl stylesheet to generate an XSL stylesheet for converting BIBFRAME descriptions encoded as RDF/XML to MARCXML.
You can generate the conversion stylesheet using xsltproc:
xsltproc src/compile.xsl rules.xml > bibframe2marc.xsl
The Makefile included with this project will generate a top-level rules.xml file in the xsl directory based on the files in the xsl/rules directory, and use that file to generate the bibframe2marc.xsl stylesheet.
rules: the root element of any rules document. Theruleselement can contain the elementsversion,file,map,cf,df,select, andswitch. The order of the rules determines the field order of the generated MARC record.
<rules xmlns="http://www.loc.gov/bf2marc">
<version>0.1.0-SNAPSHOT</version>
<file>rules/00-LDR.xml</file>
<cf tag="001">
<transform><xsl:value-of select="$pRecordId"/></transform>
</cf>
<df tag="500">
<ind1 default=" "/>
<ind2 default=" "/>
<sf code="a">
<transform>MARC record generated by DLC bibframe2marc <xsl:value-of select="$vCurrentVersion"/><xsl:if test="$pGenerationDatestamp != ''">: <xsl:value-of select="$pGenerationDatestamp"/></xsl:if></transform>
</sf>
</df>
</rules>version: the version of the conversion rules. Populates thevCurrentVersionvariable of the generated stylesheet. Only the top-levelversionelement is processed (the version is not processed for any included files).
<version>0.1.0-SNAPSHOT</version>file: the path to a file containing another rules document relative the to current directory. This provides a mechanism for splitting up the conversion rules into more manageable chunks. Rules files can be included to an arbitrary depth.
<file>rules/00-LDR.xml</file>map: Create a lookup table. Themapelement should contain a flat XML data structure. It has a requirednameattribute. It creates a variable with the name of thenameattribute in the stylesheet that contains the data structure specified. This data structure can then be referenced in XPath expressions with the exsl:node-set() function or using thelookupelement.
<bf2marc:rules xmlns:bf2marc="http://www.loc.gov/bf2marc">
<bf2marc:map name="instruments">
<instrument>
<code>ba</code>
<type>brass</type>
<label>horn</label>
</instrument>
<instrument>
<code>bb</code>
<type>brass</type>
<label>trumpet</label>
</instrument>
</bf2marc:map>
</bf2marc:rules>key: Build an XSLT key from a set of elements in the source document. Thekeyelement creates anxsl:keyin the output stylesheet with the same attributes. This key can then be referenced in XPath expressions or XSL fragments.
<key name="kMusicMediumSource" match="bf:MusicMedium" use="bf:source/bf:Source/rdfs:label"/>Two high-level elements are used to encode the conversion rules that generate MARC fields.
cf: conversion rules for the generating MARC leader and control fields. These rules should generate strings. Thecfelement requires atagattribute. The special attribute valuetag="LDR"will generate a MARC leader. The optional attributechopPunct, if set to "true", will remove enclosing parentheses brackets, braces, and quotes, and ending punctuation except for a period or ellipsis.
<cf tag="001">
<transform><xsl:value-of select="$pRecordId"/></transform>
</cf>df: conversion rules for generating MARC data fields. Thedfelement requires atagattribute, which should contain a 3-character value. An optional boolean attribute,repeatable, if set to"false"will prevent the data field from being generated more than once. The optional attributelang-xpathholds an XPath expression for a single property with anxml:langattribute that can be used to generate anxml:langtag attribute on the data field. Note: using an expression likerdfs:label|bf:codewill result in unexpected results! The optional attributelang-prefergenerates processing code that attempts to prefer vernacular or transliterated versions of literals, based on thelang-xpathand the cataloging language script parameterpCatScript.
The df element is more complex. In addition to the rule building blocks documented below, the following elements are required:
ind1: rule for generating the first indicator of the MARC data field. Theind1element requires adefaultattribute. This rule should generate a single character legal for a MARC indicator.ind2: rule for generating the second indicator of the MARC data field. Theind2element requires adefaultattribute. This rule should generate a single character legal for a MARC indicator.sf: rules for generating MARC subfield values. At least onesfelement is required. Thesfelement requires acodeattribute, which should contain a 1-character value legal for a MARC subfield code. The optional attributechopPunct, if set to "true", will remove enclosing parentheses brackets, braces, and quotes, and ending punctuation except for a period or ellipsis. This element is repeatable within thedfelement. The order ofsfelements determines the order of subfields in the generated MARC data field. An optional boolean attribute,repeatable, if set to"false", will prevent the subfield from being generated more than once. These rules should generate strings.
<df tag="500" lang-xpath="rdfs:label">
<ind1 default=" "/>
<ind2 default=" "/>
<sf code="a">
<transform>MARC record generated by DLC bibframe2marc <xsl:value-of select="$vCurrentVersion"/><xsl:if test="$pGenerationDatestamp != ''">: <xsl:value-of select="$pGenerationDatestamp"/></xsl:if></transform>
</sf>
</df>-
Bare values: A bare value in an element will generate a constant value in the MARC data element. Note that if there is a bare value in an element, any other processing rules will be ignored. If a bare value is enclosed in a
textelement, leading and trailing white space will be preserved.- Bare values can be used with the
cf,ind1,ind2,sf,position,select, andcaseelements.
- Bare values can be used with the
<df tag="500">
<ind1 default=" "/>
<ind2 default=" "/>
<sf code="a">MARC record generated by DLC bibframe2marc</sf>
</df>-
context: Set the context for the contained processing rules. Required attributexpathcontains an XPath path expression to set the context. Any XPath expressions in the contained elements will be evaluated in the context set by the containingcontextelement. If the context is not matched in the source document, the MARC element will not be generated. Generates anxsl:templateorxsl:for-eachelement in the output stylesheet. Note that multiple context blocks in non-repeatable fields are not allowed. If there is acontextblock in an element, other processing rules will be ignored.- This element can be used with the
cfanddfelements.
- This element can be used with the
<cf tag="003">
<context xpath="rdf:RDF/bf:Work/bf:adminMetadata/bf:AdminMetadata/bf:source/bf:Source/bf:code">
<select xpath="."/>
</context>
</cf>-
fixed-field/position: Generate a string for use in a fixed-length fields. Afixed-fieldelement must contain one or morepositionelements, the results of which will be concatenated to generate the value for the target MARC data element. Thepositionelement has a requireddefaultattribute.- These elements can be used with the
cfandsfelements.
- These elements can be used with the
<cf tag="LDR">
<fixed-field>
<position default=" "/>
<position default="n">
<select xpath="substring(rdf:RDF/bf:Work/bf:adminMetadata/bf:AdminMetadata/bf:status/bf:Status/bf:code,1,1)"/>
</position>
</fixed-field>
</cf>-
select: Use an XPath path expression to select a value for use in the target MARC data element, or a value or nodeset for processing. The output of aselectelement should be a string for use in a MARC data element. Note that theselectelement will also set the context for any contained XPath expressions. Theselectelement generates anxsl:for-eachelement in the output stylesheet. In the context of a non-repeatable field or subfield, multipleselectelements are not allowed.- This element can be used with the
rules,cf,ind1,ind2,sf,position, andcaseelements.
- This element can be used with the
<sf code="b" repeatable="false">
<select xpath="bf:subtitle"/>
</sf>-
var: Create a locally-scoped XSL variable within a context. The variable has the name from thenameattribute and the value from either thexpathattribute or from a internalswitchelement. The variable can be used within the current context in transforms and xpath expressions.- This element can only be used with the
contextandselectelements.
- This element can only be used with the
<select xpath="bf:title/*">
<var name="vTitleClass" xpath="local-name()"/>
<switch>
<case test="$vTitleClass=KeyTitle">
<df tag="222"/>
</case>
</switch>
</select>-
switch/case: These elements offer a form of conditional processing. Aswitchelement contains one or morecaseelements. Eachcaseelement has a requiredtestattribute, which contains an XPath expression. If the XPath expression evaluates totrue(), thecaseelement matches. The firstcaseelement to match is evaluated. If nocaseelements match, no value is generated by theswitchelement. The specialtestattribute value"default"(e.g.test="default") provides default processing, if needed.- These elements can be used with the
rules,cf,ind1,ind2,sf,position, andselectelements.
- These elements can be used with the
<sf code="a" repeatable="false">
<switch>
<case test="bf:mainTitle"><select xpath="bf:mainTitle"/></case>
<case test="rdfs:label"><select xpath="rdfs:label"/></case>
</switch>
</sf>if: This element provides basic confitional processing. Anifelement is only supported as a childe ofrulesbut can contain any other element. Eachifrequires atestattribute, which contains an XPath expression. If the XPath expression evaluates totrue(), theifelement matches.
<if test="$xslProcessor = 'libxslt'">
<switch>
<case test="bf:Work/bf:hasPart[contains(@rdf:resource, 'hubs')]
">
<transform>
<xsl:message>Record <xsl:value-of select="$vRecordId"/>:
Unprocessed relationship node(s)/Hub(s)
<xsl:value-of select="name()"/>. Repeatable target
field 7XX.</xsl:message>
</transform>
</case>
</switch>
</if>-
lookup/lookupField: These elements can be used to look up a value in a map using values from the current context, or using a static value. Thelookupelement has 2 required attributes:mapidentifies the map for the lookup, andtargetFieldidentifies the field in the map that contains the targeted value. Alookupelement contains 1 or morelookupFieldelements, which are and-ed together to search the map. ThelookupFieldelement has a requirednameattribute that identifies the map field in which to look for the value. The optionalxpathattribute contains an XPath expression in the current context to use as a lookup value. If there is noxpathattribute, the text value of thelookupFieldelement is used as the lookup value.- These elements can be used with the
cf,ind1,ind2,sf,position,caseandvarelements.
- These elements can be used with the
<df tag="048">
<context xpath="//bf:Work/bf:instrument/bf:MusicInstrument">
<ind1 default=" "/>
<ind2 default=" "/>
<sf code="a">
<lookup map="instruments" targetField="code">
<lookupField name="type">brass</field>
<lookupField name="label" xpath="rdfs:label"/>
</lookup>
</sf>
</context>
</df>-
transform: Provide an XSL fragment for processing the current context.- This element can be used with the
rules,cf,ind1,ind2,sf,position,case, andselectelements.
- This element can be used with the
<cf tag="001">
<transform><xsl:value-of select="$pRecordId"/></transform>
</cf>The following global variables in the generated stylesheet are available for use in XSL fragments and XPath expressions:
vAdminMetadata: The node set that represents thebf:AdminMetadataobject for the BIBFRAME description. By default, it is from the XPath/rdf:RDF/bf:Instance/bf:adminMetadata/bf:AdminMetadata(the top-levelbf:Instancesubject). If there is no object at that path, the variable will be created from/rdf:RDF/bf:Work/bf:adminMetadata/bf:AdminMetadata(the top-levelbf:Worksubject).vRecordId: A record ID that is calculated for the current BIBFRAME description, with this priority:- The value of the
pRecordIdparameter, if it is passed to the stylesheet - The value in
/rdf:RDF/bf:Work/bf:adminMetadata/bf:AdminMetadata/bf:identifiedBy/bf:Local/rdf:value, if there is nobf:sourceproperty or thebf:source/bf:Source/rdfs:labelvalue is "DLC". generate-id()(default)
- The value of the
vCurrentVersion: The value of theversionelement of the top-levelrulesdocument.
In addition, the following string parameters can be passed to the stylesheet and used as global variables in XSL fragments and XPath expressions:
pRecordId: The assigned record ID for the description, e.g. for use in the MARC 001 control field.pGenerationDatestamp: Defaults todate:date-time()orfn:current-dateTime()if the functions are available to the XSLT processer. Generated defaults are inYYYYMMDDhhmmss.0format (ISO 8601) for use in an 005 or 884.pConversionAgency: MARC organization code of the institution doing the data generation, e.g. for use in the 003 or the 884. Defaults toDLC.pCatScript: The ISO 15924 script subtag of the cataloging language, for dealing with multi-script records. Defaults toLatn.pSourceRecordId: An identifier for the source record, perhaps a URIpGenerationUri: Identifier for the generation process, e.g. a Github URL. Defaults tohttps://github.com/lcnetdev/bibframe2marc.
The following named templates are defined in the generated stylesheet for use in XSL fragments:
tChopPunct: Chops enclosing quotes, parens, brackets, and end punctuation. Used internally when stylesheet parameterspChopPunctis "true".tPadRight: Return a right-padded string.tPadLeft: Return a left-padded string.EDTF-Date1: Return the first date from an EDTF date range. If the EDTF date is not a range, will simply return the date.EDTF-Date2: Return the second date from an EDTF date range. If the EDTF date is not a range, will return an empty string.EDTF-DatePart: Return the date part of a single EDTF date (not a range).EDTF-TimePart: Return the time part of a single EDTF date (not a range).EDTF-TimeDiff: Return the time shift part of a single EDTF date (not a range).EDTF-to-033: Return a string formatted as a date for the 033/263 fields from a single EDTF date (not a range).tScriptCode: Extract the script subtag from an xml:lang attribute.tUriCode: Extract the code (last path element) of an id.loc.gov URItToken2Subfields: Tokenize a string into a set of subfieldstGetRelResource: Return a MARC record. Template will convert marcKey to small MARC record or calltGetMARCAuth. MARC record may be an authority or BibHub. If using xsltproc, must process template result set with exsl:node-set().tGetMARCAuth: Return a MARC record from id.loc.gov as a node set. Note special processing for LOC authorities retrieves an SRU result set, so you may need to dig for the MARC record to use the values! See the test examples in rules/test/test/04-1XX.xspec.tGetLabel: Return a label for a resource based in URI. Expects to lookup data at ID.LOC.GOV. Will not work with xsltproc.
- The behavior of
contextandselectblocks in a non-repeatable field is somewhat limiting. For a non-repeatable field, there can only be onecontextorselectblock. - Lookup support is aggravated by xsltproc limitations, principally a lack of support for HTTPS.
The generated stylesheet uses the following namespace prefixes:
rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#rdfs:http://www.w3.org/2000/01/rdf-schema#marc:http://www.loc.gov/MARC21/slimbf:http://id.loc.gov/ontologies/bibframe/bflc:http://id.loc.gov/ontologies/bflc/madsrdf:http://www.loc.gov/mads/rdf/v1#xsl:http://www.w3.org/1999/XSL/Transformlocal:local:
These prefixes should be used in any XPath expressions and embedded XSL fragments to support XSL transformation. For your rules documents to validate, you may need to import these namespaces, along with the bf2marc namespace.