Custom-Import¶
Motivation¶
VL kann bibliographische Standards wie z.B. mabxml
oder marc
direkt importieren. Es gibt jedoch auch
Formate, die nur explizit in einer Domain gemapped werden können.
Für diese Aufgabe müssen XSL-Transformationen implementiert werden.
Konfiguration¶
Die Konfiguration wird an der gewünschten Domain abgelegt:
[imports]
[[custom]]
# activate feature
on = boolean(default=False)
# trigger on these file extensions in import directory
extensions = string_list(default=list('.xml'))
# generate data records from input file
# splitmode = dumb: use children of root element as data records
splitmode = option(dumb, trafo, mets, default=dumb)
# splitmode = trafo: split input file into data records that are stored
# in OM_XML/rawCatalogData and fed into mapper trafo
splitter = string(default='splitter.xsl')
# map data records to MODS
# also used for splitting in splitmode = mets
mapper = string(default='xml2mods.xsl')
Beispiele¶
Die folgenden Beispiele operieren auf einer modsList
mit zwei Datenpaketen
in einer Datei mit dem Namen example_list.mods
. Um auf *.mods
Dateien zu triggern, wird
imports.custom.extensions = .mods
gesetzt.
<modsList xmlns="http://www.loc.gov/mods/v3" version="3.5">
<mods>
<recordInfo>
<recordIdentifier>ABCDEF_0</recordIdentifier>
</recordInfo>
</mods>
<mods>
<recordInfo>
<recordIdentifier>ABCDEF_1</recordIdentifier>
</recordInfo>
</mods>
</modsList>
splitmode = dumb
¶
Der dumb
Default-Mode ist in VL immer verfügbar. In diesem Modus werden einfach alle /*
Elemente unter dem
root-Tag modsList
als Datenpakete verstanden. Der Dokumenttyp kann nicht beeinflusst werden.
Ein passender imports.custom.mapper
ohne weitere Logik hätte die Form:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mods="http://www.loc.gov/mods/v3">
<xsl:template match="/">
<mods:mods>
<mods:titleInfo>
<mods:title>
<xsl:value-of select="//mods:recordIdentifier"/>
</mods:title>
</mods:titleInfo>
<mods:recordInfo>
<mods:recordIdentifier>
<xsl:value-of select="//mods:recordIdentifier"/>
</mods:recordIdentifier>
</mods:recordInfo>
</mods:mods>
</xsl:template>
</xsl:stylesheet>
Der mapper
kopiert also einfach die mods:recordIdentifier
aus dem
Quell-MODS nach mods:title
und mods:recordIdentifier
im Ziel-MODS.
splitmode = trafo
¶
Im trafo
Mode muss eine XSL-Transformation mit konfigurierbaren Namen aus
imports.custom.splitter
implementiert werden. Eine solche splitter.xsl
für das modsList
Beispiel könnte folgende Form haben:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mods="http://www.loc.gov/mods/v3">
<xsl:template match="/">
<records>
<xsl:apply-templates/>
</records>
</xsl:template>
<xsl:template match="mods:mods">
<record type="book">
<xsl:copy-of select="."/>
<more data="from outer scope can be collected here"/>
</record>
</xsl:template>
</xsl:stylesheet>
Der Namen des root Elements (hier <records>
) und der Kinder (hier <record>
) sind
beliebig. Am <record>
Element kann der mit @type
der VL-Dokumenttyp festgelegt werden.
Im Gegensatz zum dumb
Splitter können die Datenpakete frei aus dem gesamten Eingabedokument
zusammengestellt werden.
Ein passender Mapper hat folgende Form:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mods="http://www.loc.gov/mods/v3">
<!-- match nested output of splitter.xsl -->
<xsl:template match="/record/mods:mods">
<!-- like dumb mode mapper above -->
</xsl:template>
</xsl:stylesheet>
splitmode = mets
¶
Im mets
Mode muss ein METS im VL-Import-Profile via Mapper generiert werden. Gleichzeitig muss der Mapper Einzelpakete
nach MODS mappen können. Die Einzelpakete für die Rohdaten müssen im METS neben den MODS-Paketen dmdSec/mdWrap[@MDTYPE=MODS]
in
mdWrap[@MDTYPE=rawCatalogData]
abgelegt werden. Ein solcher Mapper hätte die Form:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mods="http://www.loc.gov/mods/v3" xmlns:mets="http://www.loc.gov/METS/">
<!-- generate METS if root element is modsList (initial import mode) -->
<xsl:template match="/mods:modsList">
<mets:mets>
<xsl:for-each select="//mods:mods">
<xsl:variable name="idn" select="mods:recordInfo/mods:recordIdentifier"/>
<mets:dmdSec ID="DMD_{$idn}">
<mets:mdWrap MIMETYPE="text/xml" MDTYPE="MODS">
<mets:xmlData>
<mods:mods>
<mods:titleInfo>
<mods:title><xsl:value-of select="$idn"/></mods:title>
</mods:titleInfo>
<mods:recordInfo>
<mods:recordIdentifier>
<xsl:value-of select="$idn"/>
</mods:recordIdentifier>
</mods:recordInfo>
</mods:mods>
</mets:xmlData>
</mets:mdWrap>
<!-- stored in DB and used for MD-Update if mapper changed -->
<mets:mdWrap MIMETYPE="text/xml" MDTYPE="rawCatalogData">
<mets:xmlData>
<!-- only one element allowed here, we will only store first child -->
<xsl:copy-of select="."/>
</mets:xmlData>
</mets:mdWrap>
</mets:dmdSec>
</xsl:for-each>
<mets:structMap TYPE="logical">
<xsl:for-each select="//mods:recordIdentifier">
<mets:div TYPE="book" DMDID="DMD_{.}"/>
</xsl:for-each>
</mets:structMap>
</mets:mets>
</xsl:template>
<!-- map raw mods from mdWrap/rawCatalogData during metadata update mode -->
<xsl:template match="/mods:mods">
<!-- share mapping with mets-generator -->
</xsl:template>
</xsl:stylesheet>