2022.06
Die Nutzung von XSLT3
Der Abschnitt beschreibt die Nutzung von XSLT3 zur Transformation von Layouts und Daten sowie die zusätzlichen MyCoRe-XSLT3-Funktionen.
Standardverhalten
Mit LTS 2022.06 ist Saxon und damit XSLT3 der Standardtransormer Prozess für alle Transformationen. Die Rückkehr zu XSLT1 ist über das
folgende Property möglich.
1
|
MCR.LayoutService.TransformerFactoryClass=org.apache.xalan.processor.TransformerFactoryImpl
|
Einbindung von Saxon in die MyCoRe-Transformation
In MyCoRe ist es möglich, einzelne gekapselte Transformationsprozesse, z. B. für Datenexporte, generieren von PDF-Dateien
u. ä. bereits auf XSLT3 umzustellen, ohne dies schon für die Gesamtanwendung tun zu müssen.
Saxon
ist dabei das Mittel der Wahl.
Um einen einzelnen Transformationsprozess umzustellen, sind folgende Konfigurations-Properties notwendig:
1
2
3
|
MCR.ContentTransformer.{my_process}.Class=org.mycore.common.content.transformer.MCRXSLTransformer
MCR.ContentTransformer.{my_process}.Stylesheet=xsl/{my_stylesheet}.xsl
MCR.ContentTransformer.{my_process}.TransformerFactoryClass=net.sf.saxon.TransformerFactoryImpl
|
Wird die TransformerFactoryClass nicht gesetzt, ist Xalan der Fallback.
Unabhängig davon kann durch Konfiguration auch die gesamte Anwendung auf XSLT3 (Saxon) umgestellt werden, wenn dies
alle verwendeten Transformations-Stylesheets unterstützen:
1
|
MCR.LayoutService.TransformerFactoryClass=net.sf.saxon.TransformerFactoryImpl
|
Developer-Modus
Durch Setzen einiger Properties im Entwicklungssystem lässt sich die Arbeit mit XSLT-Stylesheets vereinfachen.
So können Stylesheets zur Laufzeit überschrieben werden, ohne die Anwendung neu bauen zu müssen.
Die Details sind auf der Seite Developer-Tools beschrieben.
Migrationshinweise XSLT1 nach XSLT3
Grundsätzlich stehen bei XSLT3 keine XALAN-Extensions mehr zur Verfügung. Diese müssen bei der Migration ersetzt werden. Weiterhin
sind die folgenden Code-Stellen zu überarbeiten. Diese Anleitung soll Hinweise zur Umstellung geben.
Ersetzung i18n:translate
XSLT1-Code
1
|
<xsl:value-of xmlns:i18n="xalan://org.mycore.services.i18n.MCRTranslation" select="i18n:translate({i18n_property_string})" />
|
XSLT3-Code
1
2
3
|
<xsl:value-of xmlns:mcri18n="http://www.mycore.de/xslt/i18n" select="mcri18n:translate({i18n_property_string})" />
oder
<xsl:value-of select="document(concat('i18n:',{i18n_property_string}))/i18n/text()" />
|
Ersetzung exsl:node-set
XSLT1-Code
1
|
<xsl:for-each xmlns:exsl="http://exslt.org/common" select="exsl:node-set($list)/node()">
|
XSLT3-Code
1
|
<xsl:for-each select="$list">
|
Ersetzung xalan:nodeset
XSLT1-Code
1
2
3
|
<xsl:for-each select="xalan:nodeset($result)/content">
...
</xsl:for-each>
|
XSLT3-Code
1
2
3
|
<xsl:for-each select="$result/content">
...
</xsl:for-each>
|
Ersetzung encoder:encode
XSLT1-Code
1
|
<xsl:variable name="url" xmlns:encoder="xalan://java.net.URLEncoder" select="encoder:encode(string($RequestURL))" />
|
XSLT3-Code
1
|
<xsl:vaiable name="url" xmlns:fn="http://www.w3.org/2005/xpath-functions" select="fn:encode-for-uri($RequestURL)" />
|
Ersetzung decoder:decode
XSLT1-Code
1
|
<xsl:variable name="url" xmlns:decoder="xalan://java.net.URLDecoder" select="decoder:decode(string($paramValue),'UTF-8')" />
|
XSLT3-Code
1
|
<xsl:vaiable name="url" select="$paramValue" disable-output-escaping="yes" />
|
Ersetzung str:tokenizer
XSLT1-Code
1
2
3
|
<xsl:for-each xmlns:str="http://exslt.org/strings" select="str:tokenize($MCR.Mail.Recipients,',')">
...
</xsl:for-each>
|
XSLT3-Code
1
2
3
|
<xsl:for-each xmlns:fn="http://www.w3.org/2005/xpath-functions" select="fn:tokenize($MCR.Mail.Recipients,',')">
...
</xsl:for-each>
|
MyCoRe XSLT3 Funktionen
MyCoRe stellt für bestimmte Aufgaben (Mehrsprachigkeit, Verarbeitung von Klassifikationen, ...)
eigene XSLT3-Funktionen als Alternative zu den URI-Resolvern bereit.
Diese Funktionen werden im Folgenden beschrieben. Jedes der angegebenen Stylesheets muss dabei inkludiert werden.
Weiterhin muss der jeweilige Namespace definiert werden.
I18N Integration
MyCoRe-Komponente: |
mycore-base |
Stylesheet: |
xslt/functions/i18n.xsl |
Namespace: |
xmlns:mcri18n="http://www.mycore.de/xslt/i18n" |
Für die Integration von I18N-Properties sind zwei XSLT-Funktionen konzipiert. Die erste Funktion enthält als Argument
nur den String des einzelnen Properties. In der zweiten Variante können der Transformation zusätzliche Argumente
mitgegeben werden.
mcri18n:translate()
1
2
|
<xsl:value-of select="mcri18n:translate({i18n_property_string})" />
<xsl:value-of select="mcri18n:translate('my_message_string')" />
|
mcri18n:translate-with-params()
1
2
|
<xsl:value-of select="mcri18n:translate-with-params({i18n_property_string}, ({arg_1}, ...))" />
<xsl:value-of select="mcri18n:translate-with-params('my_message_string_with_args', ('arg_1', 'arg_2'))" />
|
XSLT3-Funktionen für Zugriffsrechte
MyCoRe-Komponente: |
mycore-base |
Stylesheet: |
xslt/functions/acl.xsl |
Namespace: |
xmlns:mcracl="http://www.mycore.de/xslt/acl" |
mcracl:check-permission()
Es wurde eine XSLT Funktion konzipiert, welche die Zugriffsrechte für Objekte und Permissions testet und eine
boolschen Wert als Ergebnis zurückgibt.
Die Funktion hat zwei Parameter id und permission.
Dabei kann id auch den Wert der leeren Sequenz () annehmen.
1
2
|
mcracl:check-permission({id}, {permission})
mcracl:check-permission((), {permission})
|
Hier die Beispiele dazu:
1
2
|
mcracl:check-permission('mir_mods_00004711', 'delete')
mcracl:check-permission((), 'create-mods')
|
XSLT3-Funktionen für MyCoRe-Properties
MyCoRe-Komponente: |
mycore-base |
Stylesheet: |
xslt/functions/property.xsl |
Namespace: |
xmlns:mcrproperty="http://www.mycore.de/xslt/property" |
mcrproperty:one()
Diese Funktion gibt den Wert eines einzelnen Properties als String zurück.
Im Parameter key wird der Schlüssel des Properties übergeben.
zum Beispiel:
1
2
3
4
|
<h3><xsl:value-of select="mcrproperty:one('MCR.NameOfProject')" /></h3>
<!-- Ausgabe: -->
<h3>MIR</h3>
|
mcrproperty:all()
Diese Funktion gibt eine Liste von Properties zurück.
Im Parameter keyPrefix wird das Prefix für die Schlüssel der benötigten Properties übergeben.
1
|
mcrproperty:all({keyPrefix})
|
zum Beispiel:
1
2
3
4
5
6
7
8
9
10
|
<xsl:variable name="props" select="mcrproperty:all('MCR.Solr.Core.')" />
<xsl:copy-of select="$props" />
<!-- Ausgabe: -->
<properties>
<entry key="MCR.Solr.Core.main.Name">mir_main</entry>
<entry key="MCR.Solr.Core.classification.Name">mir_class</entry>
<entry key="MCR.Solr.Core.main.ServerURL">http://localhost:8983/</entry>
<entry key="MCR.Solr.Core.classification.ServerURL">http://localhost:8983/</entry>
</properties>
|
1
2
3
4
5
6
7
8
9
|
<xsl:for-each select="mcrproperty:all('MCR.Solr.Core.')/entry">
<span><xsl:value-of select="@key" /> = <xsl:value-of select="." /></span>
</xsl:for-each>
<!-- Ausgabe: -->
<span>MCR.Solr.Core.main.Name = mir_main</span>
<span>MCR.Solr.Core.classification.Name = mir_class</span>
<span>MCR.Solr.Core.main.ServerURL = http://localhost:8983/</span>
<span>MCR.Solr.Core.classification.ServerURL = http://localhost:8983/</span>
|
mcrproperty:map()
Diese Funktion gibt eine XSL-Map von Properties zurück.
Im Parameter keyPrefix wird das Prefix für die Schlüssel der benötigten Properties übergeben.
1
|
mcrproperty:map({keyPrefix})
|
zum Beispiel:
1
2
3
4
5
|
<xsl:variable name="propMap" select="mcrproperty:map('MCR.Solr.Core.')" />
<span><xsl:value-of select="map:get($propMap, 'MCR.Solr.Core.main.Name')" /></span>
<!-- Ausgabe: -->
<span>mir_main</span>
|
XSLT3-Funktionen für MODS
MyCoRe-Komponente: |
mycore-mods |
Stylesheet: |
xslt/functions/mods.xsl |
Namespace: |
xmlns:mcrmods="http://www.mycore.de/xslt/mods" |
mcrmods:to-mycoreclass()
liefert Klassifikationsdaten im MyCoRe-XML-Format zurück für ein Element (1. Parameter) und einen mode
(2. Parameter). Der erste Parameter ist ein MODS-Element, das ggf. eine Klassifikationsangabe enthält
(siehe mcrmods:is-supported()).
Der mode
-Parameter kann entweder parent oder single sein.
Bei parent werden alle Elternkategorien mit ausgeliefert (die gesuchte Kategorie ist also die, die keine
Kinder mehr enthält). Bei single wird nur die gewünschte Kategorie
mit allen Labels zurückgeliefert - eingebettet in das bekannte mycoreclass-XML-Element.
Hier ein Beispiel dazu:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<xsl:variable name="diniclass">
<mods:classification displayLabel="dini"
authorityURI="http://mycore.de/mir/classifications/diniPublType"
valueURI="http://mycore.de/mir/classifications/diniPublType#StillImage" />
</xsl:variable>
<xsl:copy-of select="mcrmods:to-mycoreclass($diniclass/*, 'single')" />
<!-- Ausgabe: -->
<mycoreclass ID="diniPublType">
<label xml:lang="en" text="DINI publication- and document types" description="general vocabulary..." />
<label xml:lang="de" text="DINI Publikations- und Dokumenttypen" description="Gemeinsames Vokabular..." />
<categories>
<category ID="StillImage">
<label xml:lang="en" text="still image" />
<label xml:lang="de" text="Einzelbild" description="Eine statische visuelle Darstellung.." />
</category>
</categories>
</mycoreclass>
<xsl:copy-of select="mcrmods:to-mycoreclass($diniclass/*, 'parent')" />
<!-- Ausgabe: -->
<mycoreclass ID="diniPublType">
<label xml:lang="en" text="DINI publication- and document types" description="general vocabulary..." />
<label xml:lang="de" text="DINI Publikations- und Dokumenttypen" description="Gemeinsames Vokabular..." />
<categories>
<category ID="Image">
<label xml:lang="de" text="Bild" description="Eine nicht textgebundene visuelle Darstellung..."/>
<label xml:lang="en" text="image" description="A visual representation other than text." />
<category ID="StillImage">
<label xml:lang="en" text="still image" />
<label xml:lang="de" text="Einzelbild" description="Eine statische visuelle Darstellung..." />
</category>
</category>
</categories>
</mycoreclass>
|
mcrmods:to-category()
liefert für ein gegebenes Element ein MyCoRe-Category-XML-Element zurück. Der Parameter ist ein MODS-Element,
das ggf. eine Klassifikationsangabe enthält (s.o.).
Es wird das <category> XML-Element mit allen Labels zurückgeliefert.
Hier ein Beispiel dazu:
1
2
3
4
5
6
|
<xsl:copy-of select="mcrmods:to-category($diniclass/*)" />
<!-- Ausgabe: -->
<category ID="StillImage">
<label xml:lang="en" text="still image" />
<label xml:lang="de" text="Einzelbild" description="Eine statische visuelle Darstellung..." />
</category>
|
mcrmods:mcrmods:to-uri() internal
liefert für ein Element eine modsclass:-URI zurück für den
MCRModsClassificationURIResolver, wenn das Element eine
Klassifikationsangabe enthält (z.B. über @authorityURI und @valueURI). Diese Funktion wird hauptsächlich intern verwendet.
Hier ein Beispiel dazu
1
2
3
4
5
6
7
8
9
|
<xsl:variable name="modsclass">
<mods:classification authorityURI="http://mycore.de/mir/classifications/accesscondition"
valueURI="http://mycore.de/mir/classifications/accesscondition#openaccess"
displayLabel="accesscondition">frei zugänglich (Open Access)</mods:classification>
</xsl:variable>
<xsl:value-of select="mcrmods:to-uri($modsclass/*)" />
<!-- Ausgabe: -->
modsclass:/uri/http%3A%2F%2Frosdok.uni-rostock.de%2Fclassifications%2Faccesscondition/http%3A%2F%2Frosdok.uni-rostock.de%2Fclassifications%2Faccesscondition%23openaccess
|
mcrmods:is-supported() internal
gibt true für ein MODS-Element (s.o.) zurück, wenn es prinzipiell geeignet ist eine Klassifikationsangabe
zu enthalten. Das ist eine hauptsächlich intern benutzte Hilfsfunktion.
Hier die Beispiele dazu:
1
2
|
mcrmods:is-supported(mods:classification) —> IMMER true
mcrmods:is-supported(/mycoreobject) —> IMMER false
|
XSLT3-Funktionen für Klassifikationen
MyCoRe-Komponente: |
mycore-base |
Stylesheet: |
xslt/functions/classification.xsl |
Namespace: |
xmlns:mcrclass="http://www.mycore.de/xslt/classification" |
mcrclass:current-label()
gibt für ein MyCoRe-Klassifikations-Element oder ein MyCoRe-Category-Element das Label-Element
in der aktuellen Sprache zurück. Als Fallback wird zuerst versucht, das Label der Default-Sprache und anschließend
das erste Label der Klassifikation zurückzuliefern.
1
2
3
4
5
6
7
8
9
10
|
<xsl:variable name="categ">
<category ID="published">
<label xml:lang="en" text="published" />
<label xml:lang="de" text="veröffentlicht" />
</category>
</xsl:variable>
<xsl:value-of select="mcrclass:current-label($categ/*)" />
<!-- Rückgabe (in deutsch-sprachiger Anwendung): -->
<label xml:lang="de" text="veröffentlicht" />
|
mcrclass:current-label-text()
verhält sich wie die vorhergehende Funktion, gibt jedoch direkt den Wert des Labels für die Anzeige zurück.
1
2
3
4
|
<xsl:value-of select="mcrclass:current-label-text($categ/*)" />
<!-- Rückgabe (in deutsch-sprachiger Anwendung): -->
veröffentlicht
|
Diese Funktionen lassen sich auch mit den Funktionen für MODS kombinieren, z.B.:
1
2
3
4
|
Label: <xsl:value-of select="mcrclass:current-label-text(mcrmods:to-category($diniclass/*))" />
<!-- Rückgabe (in deutsch-sprachiger Anwendung): -->
Label: Einzelbild
|