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. Therules
element 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 thevCurrentVersion
variable of the generated stylesheet. Only the top-levelversion
element 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. Themap
element should contain a flat XML data structure. It has a requiredname
attribute. It creates a variable with the name of thename
attribute 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 thelookup
element.
<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. Thekey
element creates anxsl:key
in 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. Thecf
element requires atag
attribute. 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. Thedf
element requires atag
attribute, 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-xpath
holds an XPath expression for a single property with anxml:lang
attribute that can be used to generate anxml:lang
tag attribute on the data field. Note: using an expression likerdfs:label|bf:code
will result in unexpected results! The optional attributelang-prefer
generates processing code that attempts to prefer vernacular or transliterated versions of literals, based on thelang-xpath
and 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. Theind1
element requires adefault
attribute. This rule should generate a single character legal for a MARC indicator.ind2
: rule for generating the second indicator of the MARC data field. Theind2
element requires adefault
attribute. This rule should generate a single character legal for a MARC indicator.sf
: rules for generating MARC subfield values. At least onesf
element is required. Thesf
element requires acode
attribute, 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 thedf
element. The order ofsf
elements 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
text
element, leading and trailing white space will be preserved.- Bare values can be used with the
cf
,ind1
,ind2
,sf
,position
,select
, andcase
elements.
- 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 attributexpath
contains an XPath path expression to set the context. Any XPath expressions in the contained elements will be evaluated in the context set by the containingcontext
element. If the context is not matched in the source document, the MARC element will not be generated. Generates anxsl:template
orxsl:for-each
element in the output stylesheet. Note that multiple context blocks in non-repeatable fields are not allowed. If there is acontext
block in an element, other processing rules will be ignored.- This element can be used with the
cf
anddf
elements.
- 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-field
element must contain one or moreposition
elements, the results of which will be concatenated to generate the value for the target MARC data element. Theposition
element has a requireddefault
attribute.- These elements can be used with the
cf
andsf
elements.
- 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 aselect
element should be a string for use in a MARC data element. Note that theselect
element will also set the context for any contained XPath expressions. Theselect
element generates anxsl:for-each
element in the output stylesheet. In the context of a non-repeatable field or subfield, multipleselect
elements are not allowed.- This element can be used with the
rules
,cf
,ind1
,ind2
,sf
,position
, andcase
elements.
- 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 thename
attribute and the value from either thexpath
attribute or from a internalswitch
element. The variable can be used within the current context in transforms and xpath expressions.- This element can only be used with the
context
andselect
elements.
- 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. Aswitch
element contains one or morecase
elements. Eachcase
element has a requiredtest
attribute, which contains an XPath expression. If the XPath expression evaluates totrue()
, thecase
element matches. The firstcase
element to match is evaluated. If nocase
elements match, no value is generated by theswitch
element. The specialtest
attribute value"default"
(e.g.test="default"
) provides default processing, if needed.- These elements can be used with the
rules
,cf
,ind1
,ind2
,sf
,position
, andselect
elements.
- 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. Anif
element is only supported as a childe ofrules
but can contain any other element. Eachif
requires atest
attribute, which contains an XPath expression. If the XPath expression evaluates totrue()
, theif
element 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. Thelookup
element has 2 required attributes:map
identifies the map for the lookup, andtargetField
identifies the field in the map that contains the targeted value. Alookup
element contains 1 or morelookupField
elements, which are and-ed together to search the map. ThelookupField
element has a requiredname
attribute that identifies the map field in which to look for the value. The optionalxpath
attribute contains an XPath expression in the current context to use as a lookup value. If there is noxpath
attribute, the text value of thelookupField
element is used as the lookup value.- These elements can be used with the
cf
,ind1
,ind2
,sf
,position
,case
andvar
elements.
- 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
, andselect
elements.
- 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:AdminMetadata
object for the BIBFRAME description. By default, it is from the XPath/rdf:RDF/bf:Instance/bf:adminMetadata/bf:AdminMetadata
(the top-levelbf:Instance
subject). 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:Work
subject).vRecordId
: A record ID that is calculated for the current BIBFRAME description, with this priority:- The value of the
pRecordId
parameter, 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:source
property or thebf:source/bf:Source/rdfs:label
value is "DLC". generate-id()
(default)
- The value of the
vCurrentVersion
: The value of theversion
element of the top-levelrules
document.
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.0
format (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 parameterspChopPunct
is "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
context
andselect
blocks in a non-repeatable field is somewhat limiting. For a non-repeatable field, there can only be onecontext
orselect
block. - 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/slim
bf
: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/Transform
local
: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.