How to show custom metadata in DSpace's summary view? - xslt

I just "inherited" this repository in my office. I have no experience at all with it and I've been asked to show custom metadata below an item's title in the summary view. The custom metadata has already been registered (it is called dc.magazine.title) and I managed to edit the input forms so that all the new metadata can be registered in the database.
The repository is using the default mirage theme with XMLUI. I have changed some code in the file DIM-Handler.xsl trying to emulate how the other info is rendered but I have no idea how it works so my approach has given no results. This is what I tried:
<!-- Magazine row -->
<tr class="ds-table-row {$phase}">
<td><span class="bold"><i18n:text>xmlui.dri2xhtml.METS-1.0.item-title</i18n:text>: </span></td>
<td>
<xsl:choose>
<xsl:when test="count(dim:field[#element='magazine'][#qualifier='title']) = 1">
<xsl:value-of select="dim:field[#element='magazine'][#qualifier='title'][1]/node()"/>
</xsl:when>
<xsl:otherwise>
<i18n:text>xmlui.dri2xhtml.METS-1.0.no-title</i18n:text>
</xsl:otherwise>
</xsl:choose>
</td>
</tr>
<xsl:call-template name="itemSummaryView-DIM-fields">
<xsl:with-param name="clause" select="($clause + 1)"/>
<xsl:with-param name="phase" select="$otherPhase"/>
</xsl:call-template>
But nothing is showing besides the default metadata. Can somebody give me a hand on how to show this new metadata? Some clues on how this code works so I can make future changes will be really appreciated!

If you are using the default installation of DSpace using the Mirage 1 theme, the display of the item's metadata is rendered in [DSpace-installed-directory]/webapps/xmlui/themes/Mirage/lib/xsl/aspect/artifac‌​tbrowser/item-view.xsl. In my comment, I specified [DSpace-installed-directory] since I'm not so sure if the repository you 'inherited' could be using a customized theme with a different theme name other than Mirage.
You said that you are required to show a custom metadata below the item's title. Try to insert this before the <!-- Author(s) row -->
<xsl:when test="$clause = 2 and (dim:field[#element='magazine' and #qualifier='title' and descendant::text()])">
<div class="simple-item-view-other">
<span class="bold"><i18n:text>xmlui.dri2xhtml.METS-1.0.item-title</i18n:text>:</span>
<span>
<xsl:for-each select="dim:field[#element='magazine' and #qualifier='title']">
<xsl:value-of select="./node()"/>
<xsl:if test="count(following-sibling::dim:field[#element='magazine' and #qualifier='title']) != 0">
<br/>
</xsl:if>
</xsl:for-each>
</span>
</div>
<xsl:call-template name="itemSummaryView-DIM-fields">
<xsl:with-param name="clause" select="($clause + 1)"/>
<xsl:with-param name="phase" select="$otherPhase"/>
</xsl:call-template>
</xsl:when>
Please take note of the $clause number. You should update all the clause number below ie the author's row should be $clause = 3 down to the part of
<!-- IMPORTANT: This test should be updated if clauses are added! -->
<xsl:if test="$clause < 8">
<xsl:call-template name="itemSummaryView-DIM-fields">
<xsl:with-param name="clause" select="($clause + 1)"/>
<xsl:with-param name="phase" select="$phase"/>
</xsl:call-template>
</xsl:if>

#euler Thank you for your answer, with your post, (though 4 years old), I was able to make out how this simple item view works and created an entry with dc.identifier.citation. as follows
<xsl:when test="$clause = 6 and (dim:field[#element='identifier' and #qualifier='citation'])">
<div class="simple-item-view-other">
<span class="bold"><i18n:text>xmlui.ETCRiverRun.METS-1.0.item-citation</i18n:text>:</span>
<span>
<xsl:for-each select="dim:field[#element='identifier' and #qualifier='citation']">
<xsl:copy-of select="./node()"/>
<xsl:if test="count(following-sibling::dim:field[#element='identifier' and #qualifier='citation']) != 0">
<br/>
</xsl:if>````

Related

How do you get DocBook XSL's chunking to generate a full TOC for each page?

I have a bunch of DocBook XML files that all get merged into a single DocBook file for conversion into HTML. Each individual document is a reference page (for a function or similar construct). I use chunked HTML generation, so that each reference page becomes its own HTML page.
The problem is this: I want a table of contents on each page. But I don't want the table of contents for that page. I want the full TOC for the entire reference manual.
That is, from any page, I want to be able to jump to any other page by using the TOC. I can use CSS styling to stick the TOC on the left side (and even hide it for mobile viewing or whatever).
There's an obvious way to handle this. I could extract the main TOC via a post-process script and have the script copy this into each of the output HTML documents. What I'm looking for is a way to do it that works within DocBook XSL.
I want the results to look rather like DocBook XSL's newer webhelp, but with less overt JavaScript involvement.
As of 2019-07-06 with docbook-xsl-1.79.2 the currently accepted answer isn't sufficient to make each table of contents complete.
The following XSL template does, however. The key insight was stepping through with the Oxygen XML editor's debugger and noticing that while the toc-context was correctly set to the root element, the nodes variable was still the local subset.
I undid the toc-context change. Instead I created a new variable root-nodes selecting /, and edited the make.toc template to use root-nodes instead of nodes.
Putting this in my customisation layer now makes every table of contents a complete table of contents.
<xsl:template name="make.toc">
<xsl:param name="toc-context" select="."/>
<xsl:param name="toc.title.p" select="true()"/>
<xsl:param name="nodes" select="/NOT-AN-ELEMENT"/>
<xsl:variable name="root-nodes" select="/"/>
<xsl:variable name="nodes.plus" select="$root-nodes | d:qandaset"/>
<xsl:variable name="toc.title">
<xsl:if test="$toc.title.p">
<xsl:choose>
<xsl:when test="$make.clean.html != 0">
<div class="toc-title">
<xsl:call-template name="gentext">
<xsl:with-param name="key">TableofContents</xsl:with-param>
</xsl:call-template>
</div>
</xsl:when>
<xsl:otherwise>
<p>
<strong>
<xsl:call-template name="gentext">
<xsl:with-param name="key">TableofContents</xsl:with-param>
</xsl:call-template>
</strong>
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:variable>
<xsl:choose>
<xsl:when test="$manual.toc != ''">
<xsl:variable name="id">
<xsl:call-template name="object.id"/>
</xsl:variable>
<xsl:variable name="toc" select="document($manual.toc, .)"/>
<xsl:variable name="tocentry" select="$toc//d:tocentry[#linkend=$id]"/>
<xsl:if test="$tocentry and $tocentry/*">
<div class="toc">
<xsl:copy-of select="$toc.title"/>
<xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
<xsl:call-template name="toc.list.attributes">
<xsl:with-param name="toc-context" select="$toc-context"/>
<xsl:with-param name="toc.title.p" select="$toc.title.p"/>
<xsl:with-param name="nodes" select="$root-nodes"/>
</xsl:call-template>
<xsl:call-template name="manual-toc">
<xsl:with-param name="tocentry" select="$tocentry/*[1]"/>
</xsl:call-template>
</xsl:element>
</div>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$qanda.in.toc != 0">
<xsl:if test="$nodes.plus">
<div class="toc">
<xsl:copy-of select="$toc.title"/>
<xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
<xsl:call-template name="toc.list.attributes">
<xsl:with-param name="toc-context" select="$toc-context"/>
<xsl:with-param name="toc.title.p" select="$toc.title.p"/>
<xsl:with-param name="nodes" select="$root-nodes"/>
</xsl:call-template>
<xsl:apply-templates select="$nodes.plus" mode="toc">
<xsl:with-param name="toc-context" select="$toc-context"/>
</xsl:apply-templates>
</xsl:element>
</div>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$root-nodes">
<div class="toc">
<xsl:copy-of select="$toc.title"/>
<xsl:element name="{$toc.list.type}" namespace="http://www.w3.org/1999/xhtml">
<xsl:call-template name="toc.list.attributes">
<xsl:with-param name="toc-context" select="$toc-context"/>
<xsl:with-param name="toc.title.p" select="$toc.title.p"/>
<xsl:with-param name="nodes" select="$root-nodes"/>
</xsl:call-template>
<xsl:apply-templates select="$root-nodes" mode="toc">
<xsl:with-param name="toc-context" select="$toc-context"/>
</xsl:apply-templates>
</xsl:element>
</div>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Note: there is a remaining issue where not every chunked page gets its own ToC, but that is unrelated to this specific. If I sort it, I'll add a comment on how I did that.
There’s a relatively easy way to get that, though I’m pretty sure you can’t without either creating a DocBook XSL customization layer or just directly modifying the installed (system) stylesheets.
Either way, I think the actual docbook-xsl template you need to modify or override is named make.toc, located in the stylesheets distribution in the file html/autotoc.xsl.
It’s a big template—nearly a hundred lines—but you only need to make a one-line change to it:
--- /usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl 2012-12-16 11:35:12.000000000 +0900
+++ /opt/workspace/autotoc.xsl 2015-12-26 09:19:36.000000000 +0900
## -28,7 +28,7 ##
</xsl:variable>
<xsl:template name="make.toc">
- <xsl:param name="toc-context" select="."/>
+ <xsl:param name="toc-context" select="/"/>
<xsl:param name="toc.title.p" select="true()"/>
<xsl:param name="nodes" select="/NOT-AN-ELEMENT"/>
That is, you need to call that template with the toc-context param set to "/" (instead of ".").
The default "." value tells the template that, when creating a TOC for a chunk, it should only look at the (child) content of whatever element it’s currently processing (that is, the root of that particular chunk); for example, if it’s processing a section it looks only at the children of that section.
But if you instead change that value to "/", you’re telling the template to (re)look at the entire content of the source document each time. So if your document is a book, it’ll give you the entire TOC for the whole book each time, or if your document is an article, the entire article, etc.
So I think that should give you what you’re wanting.
If you decide to just modify the installed stylesheets and you’ve installed them from any OS-specific package manager you use, you need to find where the html/autotoc.xsl file is installed.
On my Debian Linux system the html/autotoc.xsl file is here:
/usr/share/xml/docbook/stylesheet/docbook-xsl/html/autotoc.xsl
And on my OS X system, installed from a homebrew package, it’s here:
/usr/local/opt/docbook-xsl/docbook-xsl/html/autotoc.xsl
If you decide to instead create a customization layer, you’ll need to copy that entire make.toc template into your customization layer (but with that toc-context param changed to "/").

XSL stylesheet: creating Hyperlink based of query item_id

I am new to coding. Started XSL coding from past 1 month.
I want to creat a hyperlink according to the item_id.
But my concat is not working as desired.
My requirement is that i have to get create hyperlinks based on the variable item_id
For example:
https://xyz.com/webpr/webpr.php?objtype=frames&g_startlink=maintain&g_startdata=194970&g_userid=msbzzh&g_session_id=6017650`
https://xyz.com/webpr/webpr.php?objtype=frames&g_startlink=maintain&g_startdata=194971&g_userid=msbzzh&g_session_id=6017650
where the variable item_id comes inbetween the link. (194970, 194971 and so on)
So here is my code:
<xsl:when test ="$propName ='item_id'">
<td>
<xsl:variable name="itemId" select="$occRef/#*[local-name()=$propName]" />
<xsl:value-of select="$itemId" />
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</td>
</xsl:when>
and i also tried like this.. But both of them didn't work out.
<xsl:value-of select="$itemId" />
UPDATED: You forgot to escape ampersands and indeed the variable was used incorrectly. See below the correct syntax.
<xsl:when test="$propName='item_id'">
<td>
<xsl:variable name="itemId" select="$occRef/#*[local-name()=$propName]"/>
<a href="{concat('https://xyz.com/webpr/webpr.php?objtype=frames&g_startlink=maintain&g_startdata=', $itemId, '&g_userid=msbzzh&g_session_id=6017650')}" target="_blank">
<xsl:value-of select="$itemId"/>
</a>
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
</td>
</xsl:when>

How to link Screenshot images to Testcase results in JUNIT report? [duplicate]

I am using the ant tasks 'junit' and 'junitreport' to run my JUnit Tests and generate a report at the end (=> "Unit Test Results").
Is it there some easy way to extend this output somehow to get more information displayed in the report? For example to add an additional column which contains link to a screenshot taken by the test.
I've seen that one could write an own ant junit test runner like the EclipseTestRunner
but this is quite some effort. Is there no API to access the elements of a unit report?
The junitreport task uses XSLT to produce the report from the XML files generated by the junittask.
You can customize the output by specifying your own XSLT using the styledir attribute of the nested report element:
<!-- use reportstyle/junit-frames.xsl to produce the report -->
<report styledir="reportstyle" format="frames" todir="testreport"/>
For customizing the the output, one option would be to make a copy of the default XSLT and modify that. Or you could look for an alternative XSLT which is more easy to customize for your purposes.
For small changes, it might be easiest to just import the default XSLT and override whatever templates you need to customize. For example, to add a column for each test, you would need to override the template which produces the table header and the template which produces a table row. Below, I have just copied those templates and modified them a bit to add one column (look for two additions marked with <!-- ADDED -->).
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- import the default stylesheet -->
<xsl:import href="jar:file:lib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl"/>
<!-- override the template producing the test table header -->
<xsl:template name="testcase.test.header">
<xsl:param name="show.class" select="''"/>
<tr valign="top">
<xsl:if test="boolean($show.class)">
<th>Class</th>
</xsl:if>
<th>Name</th>
<th>Status</th>
<th width="80%">Type</th>
<th nowrap="nowrap">Time(s)</th>
<!-- ADDED -->
<th>Screenshot</th>
</tr>
</xsl:template>
<!-- override the template producing a test table row -->
<xsl:template match="testcase" mode="print.test">
<xsl:param name="show.class" select="''"/>
<tr valign="top">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="error">Error</xsl:when>
<xsl:when test="failure">Failure</xsl:when>
<xsl:otherwise>TableRowColor</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:variable name="class.href">
<xsl:value-of select="concat(translate(../#package,'.','/'), '/', ../#id, '_', ../#name, '.html')"/>
</xsl:variable>
<xsl:if test="boolean($show.class)">
<td><xsl:value-of select="../#name"/></td>
</xsl:if>
<td>
<a name="{#name}"/>
<xsl:choose>
<xsl:when test="boolean($show.class)">
<xsl:value-of select="#name"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#name"/>
</xsl:otherwise>
</xsl:choose>
</td>
<xsl:choose>
<xsl:when test="failure">
<td>Failure</td>
<td><xsl:apply-templates select="failure"/></td>
</xsl:when>
<xsl:when test="error">
<td>Error</td>
<td><xsl:apply-templates select="error"/></td>
</xsl:when>
<xsl:otherwise>
<td>Success</td>
<td></td>
</xsl:otherwise>
</xsl:choose>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="#time"/>
</xsl:call-template>
</td>
<!-- ADDED -->
<td>
screenshot
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
Here's how the result looks like:
Also if you don't want to replace the main xsl file, you can copy xsl file into the project root folder, update it with your changes and finally edit your build.xml file adding styledir attribute:
<report styledir="." format="noframes" todir="${junit.output.dir}"/>
Awesome ans by Jukka. This is an extension to Jukka's answer as to how exactly you can link the screenshot
<!-- ADDED -->
<td>
screenshot
</td>
Instead of above snippet in Jukka's ans, here is how you can link the screenshots :
<!-- Added screenshot link for failed tests -->
<td>
<xsl:variable name="class.name">
<xsl:value-of select="translate(#classname,'.','/')"/>
</xsl:variable>
<xsl:variable name="junit.base">
<xsl:call-template name="path"><xsl:with-param name="path" select="../#package"/></xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="failure">
<xsl:value-of select="#name"/>
</xsl:when>
<xsl:when test="error">
<xsl:value-of select="#name"/>
</xsl:when>
</xsl:choose>
</td>
All you need to do after the junit report is generated is - copy all the screenshots from "selenium/screenshots/" directory right under junit_report directory.
The above code will add link only for failed tests. If you want it for all then modify code accordingly.

Strip HTML-like characters (not markup) from XML with XSLT?

Is there a way to strip all HTML from XML with XSLT,
like PHP strip_tags() ?
I want to keep the text, but remove all formatting, etc.
This will be taking place before truncating.
Hey Kurt, <br> I'd like to suggest that we start inventorying a system feature list at a <br> high-level. From there, we would define the requirements of the features. <br> Next, design to the requirements, develop, test, deploy..wash, rinse, and <br> repeat.. <br> I.E. <br> Event Calendar <br> - Requirement No. 1 <br> - Requirement No. 2
I found this solution on various places in the internet using Google:
Some examples of my research:
here, here, here
<!-- Calling the template that removes tag -->
<xsl:call-template name="remove-html">
<xsl:with-param name="text" select="{HtmlBody}"/>
</xsl:call-template>
<!-- This will remove the tag -->
<xsl:template name="remove-html">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, '<')">
<xsl:value-of select="substring-before($text, '<')"/>
<xsl:call-template name="remove-html">
<xsl:with-param name="text" select="substring-after($text, '>')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

XSL where statement

I'm looking for some help with an XSL selector:
What I need is a selector that will show the Title of a different list where the Document of the same row matches the Name field. If there is no entry, I will show a link to create a new one. Here is what I have:
<xsl:choose>
<xsl:when test="/dsQueryResponse
/Change_Types
/Rows
/Row
/#Document = #Name"/>
<xsl:value-of select="/dsQueryResponse
/Change_Types
/Rows
/Row
/#Document[
/dsQueryResponse
/Change_Types
/Rows
/Row
/#Document = #Name
]"/>
</xsl:when>
<xsl:otherwise>
<!-- Code to show link -->
</xsl:otherwise>
</xsl:choose>
If anyone could point out where I'm going wrong, it would be greatly appreciated!
In the absence of your source XML it's a complete guess, but I suspect that
#Document = #Name
should be
#Document = current()/#Name
on both occasions. Unless you really do want the Document and Name attributes of the same element to have the same value.
Here's how I did it:
A variable needed to be created for #FileLeafRef so it could be preserved to test against inside the for-each.
<xsl:variable name="document" select="#FileLeafRef"/>
<xsl:choose>
<!-- If there is an entry in the 'Tickets' list for this #FileLeafRef -->
<xsl:when test="/dsQueryResponse/Tickets/Rows/Row/#Document = $document">
<!-- Show it here -->
<xsl:for-each select="/dsQueryResponse/Tickets/Rows/Row">
<xsl:if test="#Document = $document">
<xsl:value-of select="#Title"/>
</xsl:if>
</xsl:for-each>
</xsl:when>
<!-- Else, show a link to add a new Ticket with the document auto-populated -->
<xsl:otherwise>
<xsl:call-template name="addNewItemLink">
<xsl:with-param name="list" select="'Tickets'"/>
<xsl:with-param name="document" select="#FileLeafRef"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>