XSLT Overview

From Koha Wiki
Jump to navigation Jump to search

What does XSLT do?

XSLT is used to take marcxml from zebra / elasticsearch and render as html on Opac/Staff search results and detail pages.

This is governed by the following system preferences:

variable explanation default file
OPACXSLTDetailsDisplay details page display on OPAC MARC21slim2OPACDetail.xsl
OPACXSLTListsDisplay lists pages display on OPAC (Virtual Shelves) MARC21slim2OPACResults.xsl
OPACXSLTResultsDisplay results page display on OPAC MARC21slim2OPACResults.xsl
XSLTDetailsDisplay details page display on intranet MARC21slim2intranetDetail.xsl
XSLTListsDisplay lists pages display on intranet MARC21slim2intranetResults.xsl
XSLTResultsDisplay results page display on intranet MARC21slim2intranetResults.xsl

By default, public and private lists (aka virtual shelves) use the same xslt as the search results, but the sysprefs are separate so that they can be made different.

You can use the command 'xsltproc' to transform a marcxml file into html:

xsltproc \
    koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl \
    test.marcxml > test.html

A minimal example

To understand what is going on inside the Detail.xsl and Results.xsl files, it will help to see simplified examples of the xsl and marcxml files. We'll call the first minimal.xslt.

<!DOCTYPE stylesheet >

<xsl:stylesheet
 version="1.0" 
 xmlns:marc="http://www.loc.gov/MARC21/slim" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:template match="marc:record">
    Hello, World!
    </xsl:template>

</xsl:stylesheet>

The <xsl:stylesheet> tag contains several xml namespaces, which define that xml tags that the xslt transformation will work on. www.loc.gov/MARC21/slim contains the definition for marcxml for MARC21. It defines the leader, controlfield, datafield and subfield tags that the stylesheet will be transforming.

All transformations happen inside the <xsl:template match="marc:record"> tag. Free form text inside this tag is displayed literally on the output page.

Here's a minimal marcxml record, which we'll call minimal.marcxml.

<?xml version="1.0" encoding="UTF-8"?>
<record
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
    xmlns="http://www.loc.gov/MARC21/slim">
</record>

It contains no tags inside <record>, this file simply gives the xslt tranformation a marc record to process, as is necessary in <xsl:template match="marc:record">.

Here's what happens when we run xsltproc on minimal.xslt and minimal.marcxml:

$ xsltproc minimal.xslt minimal.marcxml
<?xml version="1.0"?>

    Hello, World!
    

Because there are no marc tags to transform in minimal.marcxml, and because we didn't define any transformations in minimal.xslt, we simply print the text Hello, World!.

XSLT templates and variables

The <xsl:template> tag can also be used to define a transformation that can be called with arguments, much like a function or subroutine would be called in a programming language.

Here we have a template called printControlNumber, which takes controlnumber as an argument (in xslt, this is known as a parameter or param). This template will print the string " controlnumber is ", followed by the value of the param.

<xsl:template name="printControlNumber">
    <xsl:param name="controlnumber"/>
    controlnumber is <xsl:value-of select="$controlnumber" />
</xsl:template>

Variables are interpolated using <xsl:value-of select="$controlnumber" />.

It is also possible to create a variable outside of a template using <xsl:variable name="foo">...</xsl:variable>. The variables can be also be used via the same '$' syntax: the variable foo is dereferenced as $foo.

Example of XSLT template use

Here's an example xslt file (we'll call it template_example.xslt), which uses the printControlNumber template:

<!DOCTYPE stylesheet >
<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:template name="printControlNumber">
        <xsl:param name="controlnumber"/>
        controlnumber is <xsl:value-of select="$controlnumber" />
    </xsl:template>

    <xsl:template match="marc:record">
        <xsl:call-template name="printControlNumber">
            <xsl:with-param name="controlnumber" select="'(OCoLC)2776588'" />
        </xsl:call-template>
    </xsl:template>

</xsl:stylesheet>

We use <xsl:call-template name="printControlNumber"> to call printControlNumber, and <xsl:with-param name="controlnumber" select="'(OCoLC)2776588'" /> to pass the literal string (OCoLC)2776588 as the praram named controlnumber.

This is analagous to calling

printControlNumber( { controlnumber => '(OCoLC)2776588' } )

in Perl. Again, because we're not operating on any marcxml tags, we'll use minimal.marcxml

$ xsltproc template_example.xslt minimal.marcxml
<?xml version="1.0"?>

        controlnumber is (OCoLC)2776588

In perl terms, this would look like

#! /usr/bin/perl

sub printControlNumber {
    my $param = shift;
    print( "controlnumber is $param->{controlnumber}\n");
}

printControlNumber( { controlnumber => '(OCoLC)2776588' } );

Operating on marc tags

We'll add a 773$w tag containing (OCoLC)2776588 to our minimal minimal.marcxml file, and call it template_example2.marcxml

<?xml version="1.0" encoding="UTF-8"?>
<record
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
    xmlns="http://www.loc.gov/MARC21/slim">

  <datafield tag="773" ind1=" " ind2=" ">
    <subfield code="w">(OCoLC)2776588</subfield>
  </datafield>
</record>

The XSLT changes a bit, because we need to loop through the datafields; then we can use marc:subfield inside the select:

<!DOCTYPE stylesheet >
<xsl:stylesheet version="1.0" xmlns:marc="http://www.loc.gov/MARC21/slim" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:template name="printControlNumber">
        <xsl:param name="controlnumber"/>
        controlnumber is <xsl:value-of select="$controlnumber" />
    </xsl:template>

    <xsl:template match="marc:record">
        <xsl:for-each select="marc:datafield[@tag=773]">
            <xsl:call-template name="printControlNumber">
                <xsl:with-param name="controlnumber" select="marc:subfield[@code='w']"/>
            </xsl:call-template>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

The output looks the same, but now nothing is hardcoded in the xslt.

xsltproc template_example2.xslt template_example2.marcxml
<?xml version="1.0"?>

        controlnumber is (OCoLC)2776588

The Detail.xsl and Results.xsl files are largely built using the features above, in various combinations.

The MARC21slimUtils.xsl template library

The file

./koha-tmpl/intranet-tmpl/prog/en/xslt/MARC21slimUtils.xsl

Contains a few pre-built templates:

Name Description
extractControlNumber is used to extract the control number (record number) from MARC tags 773/80/85 [etc.] subfield $w.
m880Select Display Alternate Graphic Representation (MARC 880) for selected latin "base"tags
showRDAtag264 shows selected information from tag 264

Passing variables via xsltproc command line options

Calling xsltproc --param XXX YYY flag can be used to set variable XXX to value YYY.

Koha's sysprefs get written into the marc record:

<xsl:variable name="UseControlNumber"
              select="marc:sysprefs/marc:syspref[@name='UseControlNumber']"/>

Using xsltproc --param UseControlNumber 1 allows us to bypass the system preference and run this from the command line.

xsltproc \
    --param UseControlNumber 1 \
    koha-tmpl/opac-tmpl/bootstrap/en/xslt/MARC21slim2OPACDetail.xsl \
    test.marcxml > test.html

Here are the variables that are used, and the sysprefs that govern them:

XSLT Variable Syspref
AlternateHoldingsField AlternateHoldingsField
AlternateHoldingsSeparator AlternateHoldingsSeparator
AlternateHoldingsSubfields AlternateHoldingsField
BiblioDefaultView BiblioDefaultView
DisplayIconsXSLT DisplayIconsXSLT
DisplayOPACiconsXSLT DisplayOPACiconsXSLT
IdRef IdRef
IntranetBiblioDefaultView IntranetBiblioDefaultView
OPACBaseURL OPACBaseURL
OPACItemLocation OPACItemLocation
OPACResultsLibrary OPACResultsLibrary
OPACTrackClicks TrackClicks
OPACURLOpenInNewWindow OPACURLOpenInNewWindow
OpacSuppression OpacSuppression
Show856uAsImage Display856uAsImage
Show856uAsImage OPACDisplay856uAsImage
TraceSubjectSubdivisions TraceSubjectSubdivisions
URLLinkText URLLinkText
UseAuthoritiesForTracings UseAuthoritiesForTracings
UseControlNumber UseControlNumber
hidelostitems hidelostitems
singleBranchMode singleBranchMode
theme opacthemes