Skip to content
Snippets Groups Projects
Commit 4a8ee435 authored by Peukert, Dr. Hagen's avatar Peukert, Dr. Hagen
Browse files

basic documentation layout

parent b33a07f9
No related branches found
No related tags found
No related merge requests found
.project 0 → 100644
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>morphilo_doc</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
Software Design
===============
\begin{figure}
\centering
\includegraphics[scale=0.8]{architecture.pdf}
\caption{Morphilo Architecture}
\label{fig:architect}
\end{figure}
The architecture of a possible \emph{take-and-share}-approach for language
resources is visualized in figure \ref{fig:architect}. Because the very gist
of the approach becomes clearer if describing a concrete example, the case of
annotating lexical derivatives of Middle English and a respective database is
given as an illustration.
However, any other tool that helps with manual annotations and manages metadata of a corpus could be
substituted here instead.
After inputting an untagged corpus or plain text, it is determined whether the
input material was annotated previously by a different user. This information is
usually provided by the metadata administered by the annotation tool; in the case at
hand it is called \emph{Morphilizer} in figure \ref{fig:architect}. An
alternative is a simple table look-up for all occurring words in the datasets Corpus 1 through Corpus n. If contained
completely, the \emph{yes}-branch is followed up further -- otherwise \emph{no}
succeeds. The difference between the two branches is subtle, yet crucial. On
both branches, the annotation tool (here \emph{Morphilizer}) is called, which, first,
sorts out all words that are not contained in the master database (here \emph{Morphilo-DB})
and, second, makes reasonable suggestions on an optimal annotation of
the items. In both cases the
annotations are linked to the respective items (e.g. words) in the
text, but they are also persistently saved in an extra dataset, i.e. Corpus 1
through n, together with all available metadata.
The difference between both information streams is that
in the \emph{yes}-branch a comparison between the newly created dataset and
all of the previous datasets of this text is carried out. Within this
unit, all deviations and congruencies are marked and counted. The underlying
assumption is that with a growing number of comparable texts the
correct annotations approach a theoretic true value of a correct annotation
while errors level out provided that the sample size is large enough. How the
distribution of errors and correct annotations exactly looks like and if a
normal distribution can be assumed is still object of the ongoing research, but
independent of the concrete results, the component (called \emph{compare
manual annotations} in figure \ref{fig:architect}) allows for specifying the
exact form of the sample population.
In fact, it is necessary at that point to define the form of the distribution,
sample size, and the rejection region. The standard setting are a normal
distribution, a rejection region of $\alpha = 0.05$ and sample size of $30$ so
that a simple Gau\ss-Test can be calculated.
Continuing the information flow further, these statistical calculations are
delivered to the quality-control-component. Based on the statistics, the
respective items together with the metadata, frequencies, and, of course,
annotations are written to the master database. All information in the master
database is directly used for automated annotations. Thus it is directly matched
to the input texts or corpora respectively through the \emph{Morphilizer}-tool.
The annotation tool decides on the entries looked up in the master which items
are to be manually annotated.
The processes just described are all hidden from the user who has no possibility
to impact the set quality standards but by errors in the annotation process. The
user will only see the number of items of the input text he or she will process manually. The
annotator will also see an estimation of the workload beforehand. On this
number, a decision can be made if to start the annotation at all. It will be
possible to interrupt the annotation work and save progress on the server. And
the user will have access to the annotations made in the respective dataset,
correct them or save them and resume later. It is important to note that the user will receive
the tagged document only after all items are fully annotated. No partially
tagged text can be output.
\ No newline at end of file
This diff is collapsed.
Data Model Implementation
=========================
Data Model
==========
Conceptualization
-----------------
From both the user and task requirements one can derive that four basic
functions of data processing need to be carried out. Data have to be read, persistently
saved, searched, and deleted. Furthermore, some kind of user management
and multi-user processing is necessary. In addition, the framework should
support web technologies, be well documented, and easy to extent. Ideally, the
MVC pattern is realized.
\subsection{Data Model}\label{subsec:datamodel}
The guidelines of the
\emph{TEI}-standard\footnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/Guidelines.pdf} on the
word level are defined in line with the structure defined above in section \ref{subsec:morphologicalSystems}.
In listing \ref{lst:teiExamp} an
example is given for a possible markup at the word level for
\emph{comfortable}.\footnote{http://www.tei-c.org/release/doc/tei-p5-doc/en/html/ref-m.html}
\begin{lstlisting}[language=XML,
caption={TEI-example for 'comfortable'},label=lst:teiExamp]
<w type="adjective">
<m type="base">
<m type="prefix" baseForm="con">com</m>
<m type="root">fort</m>
</m>
<m type="suffix">able</m>
</w>
\end{lstlisting}
This data model reflects just one theoretical conception of a word structure model.
Crucially, the model emanates from the assumption
that the suffix node is on par with the word base. On the one hand, this
implies that the word stem directly dominates the suffix, but not the prefix. The prefix, on the
other hand, is enclosed in the base, which basically means a stronger lexical,
and less abstract, attachment to the root of a word. Modeling prefixes and suffixes on different
hierarchical levels has important consequences for the branching direction at
subword level (here right-branching). Left the theoretical interest aside, the
choice of the TEI standard is reasonable with view to a sustainable architecture that allows for
exchanging data with little to no additional adjustments.
The negative account is that the model is not eligible for all languages.
It reflects a theoretical construction based on Indo-European
languages. If attention is paid to which language this software is used, it will
not be problematic. This is the case for most languages of the Indo-European
stem and corresponds to the overwhelming majority of all research carried out
(unfortunately).
Implementation
--------------
As laid out in the task analysis in section \ref{subsec:datamodel}, it is
advantageous to use established standards. It was also shown that it makes sense
to keep the meta data of each corpus separate from the data model used for the
words to be analyzed.
For the present case, the TEI-standard was identified as an
appropriate markup for words. In terms of the implementation this means that
......@@ -26,3 +81,161 @@ Whereas attributes of the objecttype are specific to the repository framework, t
recognized in the hierarchy of the meta data element starting with the name
\emph{w} (line \ref{src:wordbegin}).
\begin{lstlisting}[language=XML,caption={Word Data
model},label=lst:worddatamodel,escapechar=|] <?xml version="1.0" encoding="UTF-8"?>
<objecttype
name="morphilo"
isChild="true"
isParent="true"
hasDerivates="true"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="datamodel.xsd">
<metadata>
<element name="morphiloContainer" type="xml" style="dontknow"
notinherit="true" heritable="false">
<xs:sequence>
<xs:element name="morphilo">
<xs:complexType>
<xs:sequence>
<xs:element name="w" minOccurs="0" maxOccurs="unbounded">|label{src:wordbegin}|
<xs:complexType mixed="true">
<xs:sequence>
<!-- stem -->
<xs:element name="m1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:sequence>
<!-- base -->
<xs:element name="m2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:sequence>
<!-- root -->
<xs:element name="m3" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:attribute name="type" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- prefix -->
<xs:element name="m4" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="PrefixbaseForm" type="xs:string"/>
<xs:attribute name="position" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="type" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- suffix -->
<xs:element name="m5" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="SuffixbaseForm" type="xs:string"/>
<xs:attribute name="position" type="xs:string"/>
<xs:attribute name="inflection" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<!-- stem-Attribute -->
<xs:attribute name="type" type="xs:string"/>
<xs:attribute name="pos" type="xs:string"/>
<xs:attribute name="occurrence" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<!-- w -Attribute auf Wortebene -->
<xs:attribute name="lemma" type="xs:string"/>
<xs:attribute name="complexType" type="xs:string"/>
<xs:attribute name="wordtype" type="xs:string"/>
<xs:attribute name="occurrence" type="xs:string"/>
<xs:attribute name="corpus" type="xs:string"/>
<xs:attribute name="begin" type="xs:string"/>
<xs:attribute name="end" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</element>
<element name="wordtype" type="classification" minOccurs="0" maxOccurs="1">
<classification id="wordtype"/>
</element>
<element name="complexType" type="classification" minOccurs="0" maxOccurs="1">
<classification id="complexType"/>
</element>
<element name="corpus" type="classification" minOccurs="0" maxOccurs="1">
<classification id="corpus"/>
</element>
<element name="pos" type="classification" minOccurs="0" maxOccurs="1">
<classification id="pos"/>
</element>
<element name="PrefixbaseForm" type="classification" minOccurs="0"
maxOccurs="1">
<classification id="PrefixbaseForm"/>
</element>
<element name="SuffixbaseForm" type="classification" minOccurs="0"
maxOccurs="1">
<classification id="SuffixbaseForm"/>
</element>
<element name="inflection" type="classification" minOccurs="0" maxOccurs="1">
<classification id="inflection"/>
</element>
<element name="corpuslink" type="link" minOccurs="0" maxOccurs="unbounded" >
<target type="corpmeta"/>
</element>
</metadata>
</objecttype>
\end{lstlisting}
Additionally, it is worth mentioning that some attributes are modeled as a
\emph{classification}. All these have to be listed
as separate elements in the data model. This has been done for all attributes
that are more or less subject to little or no change. In fact, all known suffix
and prefix morphemes should be known for the language investigated and are
therefore defined as a classification.
The same is true for the parts of speech named \emph{pos} in the morphilo data
model above.
Here the PENN-Treebank tagset was used. Last, the different morphemic layers in
the standard model named \emph{m} are changed to $m1$ through $m5$. This is the
only change in the standard that could be problematic if the data is to be
processed elsewhere and the change is not documented more explicitly. Yet, this
change was necessary for the MyCoRe repository throws errors caused by ambiguity
issues on the different $m$-layers.
The second data model describes only very few properties of the text corpora
from which the words are extracted. Listing \ref{lst:corpusdatamodel} depicts
only the meta data element. For the sake of simplicity of the prototype, this
data model is kept as simple as possible. The obligatory field is the name of
the corpus. Specific dates of the corpus are classified as optional because in
some cases a text cannot be dated reliably.
\begin{lstlisting}[language=XML,caption={Corpus Data
Model},label=lst:corpusdatamodel]
<metadata>
<!-- Pflichtfelder -->
<element name="korpusname" type="text" minOccurs="1" maxOccurs="1"/>
<!-- Optionale Felder -->
<element name="sprache" type="text" minOccurs="0" maxOccurs="1"/>
<element name="size" type="number" minOccurs="0" maxOccurs="1"/>
<element name="datefrom" type="text" minOccurs="0" maxOccurs="1"/>
<element name="dateuntil" type="text" minOccurs="0" maxOccurs="1"/>
<!-- number of words -->
<element name="NoW" type="text" minOccurs="0" maxOccurs="1"/>
<element name="corpuslink" type="link" minOccurs="0" maxOccurs="unbounded">
<target type="morphilo"/>
</element>
</metadata>
\end{lstlisting}
As a final remark, one might have noticed that all attributes are modelled as
strings although other data types are available and fields encoding the dates or
the number of words suggest otherwise. The MyCoRe framework even provides a
data type \emph{historydate}. There is not a very satisfying answer to its
disuse.
All that can be said is that the use of data types different than the string
leads later on to problems in the convergence between the search engine and the
repository framework. These issues seem to be well known and can be followed on
github.
\ No newline at end of file
Framework
=========
\begin{figure}
\centering
\includegraphics[scale=0.33]{mycore_architecture-2.png}
\caption[MyCoRe-Architecture and Components]{MyCoRe-Architecture and Components\protect\footnotemark}
\label{fig:abbMyCoReStruktur}
\end{figure}
\footnotetext{source: https://www.mycore.de}
To specify the MyCoRe framework the morphilo application logic will have to be implemented,
the TEI data model specified, and the input, search and output mask programmed.
There are three directories which are
important for adjusting the MyCoRe framework to the needs of one's own application. These three directories
correspond essentially to the three components in the MVC model as explicated in
section \ref{subsec:mvc}. Roughly, they are envisualized in figure \ref{fig:abbMyCoReStruktur} in the upper
right hand corner. More precisely, the view (\emph{Layout} in figure \ref{fig:abbMyCoReStruktur}) and the model layer
(\emph{Datenmodell} in figure \ref{fig:abbMyCoReStruktur}) can be done
completely via the ``interface'', which is a directory with a predefined
structure and some standard files. For the configuration of the logic an extra directory is offered (/src/main/java/custom/mycore/addons/). Here all, java classes
extending the controller layer should be added.
Practically, all three MVC layers are placed in the
\emph{src/main/}-directory of the application. In one of the subdirectories,
\emph{datamodel/def}, the datamodel specifications are defined as xml files. It parallels the model
layer in the MVC pattern. How the data model was defined will be explained in
section \ref{subsec:datamodelimpl}.
\ No newline at end of file
View
====
Conceptualization
-----------------
Lastly, the third directory (\emph{src/main/resources}) contains all code needed
for rendering the data to be displayed on the screen. So this corresponds to
the view in an MVC approach. It is done by xsl-files that (unfortunately)
contain some logic that really belongs to the controller. Thus, the division is
not as clear as implied in theory. I will discuss this issue more specifically in the
relevant subsection below. Among the resources are also all images, styles, and
javascripts.
Implementation
--------------
As explained in section \ref{subsec:mvc}, the view component handles the visual
representation in the form of an interface that allows interaction between
the user and the task to be carried out by the machine. As a
webservice in the present case, all interaction happens via a browser, i.e. webpages are
visualized and responses are recognized by registering mouse or keyboard
events. More specifically, a webpage is rendered by transforming xml documents
to html pages. The MyCoRe repository framework uses an open source XSLT
processor from Apache, Xalan.\footnote{http://xalan.apache.org} This engine
transforms document nodes described by the XPath syntax into hypertext making
use of a special form of template matching. All templates are collected in so
called xml-encoded stylesheets. Since there are two data models with two
different structures, it is good practice to define two stylesheet files one for
each data model.
As a demonstration, in listing \ref{lst:morphilostylesheet} below a short
extract is given for rendering the word data.
\begin{lstlisting}[language=XML,caption={stylesheet
morphilo.xsl},label=lst:morphilostylesheet]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns:i18n="xalan://org.mycore.services.i18n.MCRTranslation"
xmlns:acl="xalan://org.mycore.access.MCRAccessManager"
xmlns:mcr="http://www.mycore.org/" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:mods="http://www.loc.gov/mods/v3"
xmlns:encoder="xalan://java.net.URLEncoder"
xmlns:mcrxsl="xalan://org.mycore.common.xml.MCRXMLFunctions"
xmlns:mcrurn="xalan://org.mycore.urn.MCRXMLFunctions"
exclude-result-prefixes="xalan xlink mcr i18n acl mods mcrxsl mcrurn encoder"
version="1.0">
<xsl:param name="MCR.Users.Superuser.UserName"/>
<xsl:template match="/mycoreobject[contains(@ID,'_morphilo_')]">
<head>
<link href="{$WebApplicationBaseURL}css/file.css" rel="stylesheet"/>
</head>
<div class="row">
<xsl:call-template name="objectAction">
<xsl:with-param name="id" select="@ID"/>
<xsl:with-param name="deriv" select="structure/derobjects/derobject/@xlink:href"/>
</xsl:call-template>
<xsl:variable name="objID" select="@ID"/>
<!-- Hier Ueberschrift setzen -->
<h1 style="text-indent: 4em;">
<xsl:if test="metadata/def.morphiloContainer/morphiloContainer/morphilo/w">
<xsl:value-of select="metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]"/>
</xsl:if>
</h1>
<dl class="dl-horizontal">
<!-- (1) Display word -->
<xsl:if test="metadata/def.morphiloContainer/morphiloContainer/morphilo/w">
<dt>
<xsl:value-of select="i18n:translate('response.page.label.word')"/>
</dt>
<dd>
<xsl:value-of select="metadata/def.morphiloContainer/morphiloContainer/morphilo/w/text()[string-length(normalize-space(.))>0]"/>
</dd>
</xsl:if>
<!-- (2) Display lemma -->
...
</xsl:template>
...
<xsl:template name="objectAction">
...
</xsl:template>
...
</xsl:stylesheet>
\end{lstlisting}
This template matches with
the root node of each \emph{MyCoRe object} ensuring that a valid MyCoRe model is
used and checking that the document to be processed contains a unique
identifier, here a \emph{MyCoRe-ID}, and the name of the correct data model,
here \emph{morphilo}.
Then, another template, \emph{objectAction}, is called together with two parameters, the ids
of the document object and attached files. In the remainder all relevant
information from the document is accessed by XPath, such as the word and the lemma,
and enriched with hypertext annotations it is rendered as a hypertext document.
The template \emph{objectAction} is key to understand the coupling process in the software
framework. It is therefore separately listed in \ref{lst:objActionTempl}.
\begin{lstlisting}[language=XML,caption={template
objectAction},label=lst:objActionTempl,escapechar=|]
<xsl:template name="objectAction">
<xsl:param name="id" select="./@ID"/>
<xsl:param name="accessedit" select="acl:checkPermission($id,'writedb')"/>
<xsl:param name="accessdelete" select="acl:checkPermission($id,'deletedb')"/>
<xsl:variable name="derivCorp" select="./@label"/>
<xsl:variable name="corpID" select="metadata/def.corpuslink[@class='MCRMetaLinkID']/corpuslink/@xlink:href"/>
<xsl:if test="$accessedit or $accessdelete">|\label{ln:ng}|
<div class="dropdown pull-right">
<xsl:if test="string-length($corpID) &gt; 0 or $CurrentUser='administrator'">
<button class="btn btn-default dropdown-toggle" style="margin:10px" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
<span class="glyphicon glyphicon-cog" aria-hidden="true"></span> Annotieren
<span class="caret"></span>
</button>
</xsl:if>
<xsl:if test="string-length($corpID) &gt; 0">|\label{ln:ru}|
<xsl:variable name="ifsDirectory" select="document(concat('ifs:/',$derivCorp))"/>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation">
|\label{ln:nw1}|<a href="{$ServletsBaseURL}object/tag{$HttpSession}?id={$derivCorp}&amp;objID={$corpID}" role="menuitem" tabindex="-1">|\label{ln:nw2}|
<xsl:value-of select="i18n:translate('object.nextObject')"/>
</a>
</li>
<li role="presentation">
<a href="{$WebApplicationBaseURL}receive/{$corpID}" role="menuitem" tabindex="-1">
<xsl:value-of select="i18n:translate('object.backToProject')"/>
</a>
</li>
</ul>
</xsl:if>
<xsl:if test="$CurrentUser='administrator'">
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li role="presentation">
<a role="menuitem" tabindex="-1" href="{$WebApplicationBaseURL}content/publish/morphilo.xed?id={$id}">
<xsl:value-of select="i18n:translate('object.editWord')"/>
</a>
</li>
<li role="presentation">
<a href="{$ServletsBaseURL}object/delete{$HttpSession}?id={$id}" role="menuitem" tabindex="-1" class="confirm_deletion option" data-text="Wirklich loeschen">
<xsl:value-of select="i18n:translate('object.delWord')"/>
</a>
</li>
</ul>
</xsl:if>
</div>
<div class="row" style="margin-left:0px; margin-right:10px">
<xsl:apply-templates select="structure/derobjects/derobject[acl:checkPermission(@xlink:href,'read')]">
<xsl:with-param name="objID" select="@ID"/>
</xsl:apply-templates>
</div>
</xsl:if>
</xsl:template>
\end{lstlisting}
The \emph{objectAction} template defines the selection menu appearing -- once manual tagging has
started -- on the upper right hand side of the webpage entitled
\emph{Annotieren} and displaying the two options \emph{next word} or \emph{back
to project}.
The first thing to note here is that in line \ref{ln:ng} a simple test
excludes all guest users from accessing the procedure. After ensuring that only
the user who owns the corpus project has access (line \ref{ln:ru}), s/he will be
able to access the drop down menu, which is really a url, e.g. line
\ref{ln:nw1}. The attentive reader might have noticed that
the url exactly matches the definition in the web-fragment.xml as shown in
listing \ref{lst:webfragment}, line \ref{ln:tag}, which resolves to the
respective java class there. Really, this mechanism is the data interface within the
MVC pattern. The url also contains two variables, named \emph{derivCorp} and
\emph{corpID}, that are needed to identify the corpus and file object by the
java classes (see section \ref{sec:javacode}).
The morphilo.xsl stylesheet contains yet another modification that deserves mention.
In listing \ref{lst:derobjectTempl}, line \ref{ln:morphMenu}, two menu options --
\emph{Tag automatically} and \emph{Tag manually} -- are defined. The former option
initiates ProcessCorpusServlet.java as can be seen again in listing \ref{lst:webfragment},
line \ref{ln:process}, which determines words that are not in the master data base.
Still, it is important to note that the menu option is only displayed if two restrictions
are met. First, a file has to be uploaded (line \ref{ln:1test}) and, second, there must be
only one file. This is necessary because in the annotation process other files will be generated
that store the words that were not yet processed or a file that includes the final result. The
generated files follow a certain pattern. The file harboring the final, entire TEI-annotated
corpus is prefixed by \emph{tagged}, the other file is prefixed \emph{untagged}. This circumstance
is exploited for manipulating the second option (line \ref{ln:loop}). A loop runs through all
files in the respective directory and if a file name starts with \emph{untagged},
the option to manually tag is displayed.
\begin{lstlisting}[language=XML,caption={template
matching derobject},label=lst:derobjectTempl,escapechar=|]
<xsl:template match="derobject" mode="derivateActions">
<xsl:param name="deriv" />
<xsl:param name="parentObjID" />
<xsl:param name="suffix" select="''" />
<xsl:param name="id" select="../../../@ID" />
<xsl:if test="acl:checkPermission($deriv,'writedb')">
<xsl:variable name="ifsDirectory" select="document(concat('ifs:',$deriv,'/'))" />
<xsl:variable name="path" select="$ifsDirectory/mcr_directory/path" />
...
<div class="options pull-right">
<div class="btn-group" style="margin:10px">
<a href="#" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-cog"></i>
<xsl:value-of select="' Korpus'"/>
<span class="caret"></span>
</a>
<ul class="dropdown-menu dropdown-menu-right">
<!-- Anpasssungen Morphilo -->|\label{ln:morphMenu}|
<xsl:if test="string-length($deriv) &gt; 0">|\label{ln:1test}|
<xsl:if test="count($ifsDirectory/mcr_directory/children/child) = 1">|\label{ln:2test}|
<li role="presentation">
<a href="{$ServletsBaseURL}object/process{$HttpSession}?id={$deriv}&amp;objID={$id}" role="menuitem" tabindex="-1">
<xsl:value-of select="i18n:translate('derivate.process')"/>
</a>
</li>
</xsl:if>
<xsl:for-each select="$ifsDirectory/mcr_directory/children/child">|\label{ln:loop}|
<xsl:variable name="untagged" select="concat($path, 'untagged')"/>
<xsl:variable name="filename" select="concat($path,./name)"/>
<xsl:if test="starts-with($filename, $untagged)">
<li role="presentation">
<a href="{$ServletsBaseURL}object/tag{$HttpSession}?id={$deriv}&amp;objID={$id}" role="menuitem" tabindex="-1">
<xsl:value-of select="i18n:translate('derivate.taggen')"/>
</a>
</li>
</xsl:if>
</xsl:for-each>
</xsl:if>
...
</ul>
</div>
</div>
</xsl:if>
</xsl:template>
\end{lstlisting}
Besides the two stylesheets morphilo.xsl and corpmeta.xsl, other stylesheets have
to be adjusted. They will not be discussed in detail here for they are self-explanatory for the most part.
Essentially, they render the overall layout (\emph{common-layout.xsl}, \emph{skeleton\_layout\_template.xsl})
or the presentation
of the search results (\emph{response-page.xsl}) and definitions of the solr search fields (\emph{searchfields-solr.xsl}).
The former and latter also inherit templates from \emph{response-general.xsl} and \emph{response-browse.xsl}, in which the
navigation bar of search results can be changed. For the use of multilinguality a separate configuration directory
has to be created containing as many \emph{.property}-files as different
languages want to be displayed. In the current case these are restricted to German and English (\emph{messages\_de.properties} and \emph{messages\_en.properties}).
The property files include all \emph{i18n} definitions. All these files are located in the \emph{resources} directory.
Furthermore, a search mask and a page for manually entering the annotations had
to be designed.
For these files a specially designed xml standard (\emph{xed}) is recommended to be used within the
repository framework.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment