XSL stylesheet: creating Hyperlink based of query item_id - xslt

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>

Related

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

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>````

XSLT nested conditionals - how to do this

I'm quite new to xslt
I have the following xslt snippet (pseudo'ed for clarity):
<xsl:for-each select="fields/field">
<xsl:if test="field=someThing">
<div>
<!--some content output-->
<!--here by doing-->
<!--some complex stuff-->
</div>
</xsl:if>
</xsl:for-each>
But based on value of field from loop, I optionally want to do some other stuff before the closing div.
So (armed with shiny new xsl book) I thought I could do something like this:
<xsl:for-each select="fields/field">
<xsl:if test="field=someThing">
<div>
<!--some content output-->
<!--here by doing-->
<!--some complex stuff-->
<xsl:choose>
<xsl:when test="field=someThingSpecific">
<div>
<!--process some additional-->
<!--stuff here-->
</div>
<!--then close div-->
</div>
</xsl:when>
<xsl:otherwise>
<!--nothing to do here-->
<!--just close the div-->
</div>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:for-each>
But it blows up.
Apparently because the closing div has moved into the conditional xsl:choose block
So 2 questions really:
why doesnt it work as is?
how can I achieve my objective?
It's blowing up because your XSLT isn't well-formed. When you open the first div outside of the xsl:choose, you have to close it outside the xsl:choose.
Also, if you don't need to do anything in your xsl:otherwise, just do another xsl:if:
<xsl:for-each select="fields/field">
<xsl:if test="field=someThing">
<div>
<!--some content output-->
<!--here by doing-->
<!--some complex stuff-->
<xsl:if test="field=someThingSpecific">
<div>
<!--process some additional-->
<!--stuff here-->
</div>
</xsl:if>
<!--then close div-->
</div>
</xsl:if>
</xsl:for-each>

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.

xsl:variable contains nodeset. How to output nth node of variable?

I am transforming an XML document. There is an attribute #prettydate that is a string similar to "Friday, May 7, 2010". I want to split that string and add links to the month and the year. I am using the exslt:strings module and I can add any other necessary EXSLT module.
This is my code so far:
<xsl:template match="//calendar">
<xsl:variable name="prettyparts">
<xsl:value-of select="str:split(#prettydate,', ')"/>
</xsl:variable>
<table class='day'>
<thead>
<caption><xsl:value-of select="$prettyparts[1]"/>,
<a>
<xsl:attribute name='href'><xsl:value-of select="$baseref"/>?date=<xsl:value-of select="#highlight"/>&per=m</xsl:attribute>
<xsl:value-of select='$prettyparts[2]'/>
</a>
<xsl:value-of select='$prettyparts[3]'/>,
<a>
<xsl:attribute name='href'><xsl:value-of select="$baseref"/>?date=<xsl:value-of select="#highlight"/>&per=y</xsl:attribute>
<xsl:value-of select='$prettyparts[4]'/>
</a>
</caption>
<!--etcetera-->
I have verified, by running $prettyparts through a <xml:for-each/> that I am getting the expected nodeset:
<token>Friday</token>
<token>May</token>
<token>7</token>
<token>2010</token>
But no matter which way I attempt to refer to a particular <token> directly (not in a foreach) I get nothing or various errors to do with invalid types. Here's some of the syntax I've tried:
<xsl:value-of select="$prettyparts[2]"/>
<xsl:value-of select="$prettyparts/token[2]"/>
<xsl:value-of select="exsl:node-set($prettyparts/token[2])"/>
<xsl:value-of select="exsl:node-set($prettyparts/token)[2]"/>
Any idea what the expression ought to be?
ETA: Thanks to #DevNull's suggestion, the correct expression is:
<xsl:value-of select="exsl:node-set($prettyparts)[position()=2]"/>
and, I have to set the variable this way:
<xsl:variable name="prettyparts" select="str:split(#prettydate,', ')" />
Try using [position()=2] instead of [2] in your predicates.
Example:
<xsl:value-of select="$prettyparts[position()=2]"/>

Why do my XSL transformed links come out relative to the base?

<a>
<xsl:attribute name="href">
<xsl:value-of select="link" />
</xsl:attribute>
<xsl:attribute name="target">new</xsl:attribute>
<xsl:value-of select="title" />
</a>
Thats my template, and in my code:
sb.Append("<title>");
sb.AppendFormat("{0} - {1}", f.UserName, f.PointTypeDesc);
sb.Append("</title>");
sb.Append("<link>");
sb.AppendFormat("{0}", HttpUtility.UrlEncode(url));
sb.Append("</link>");
url is "http://www.cnn.com"
But it renders as: "http://localhost/http://www.cnn.com"
any ideas?
It seems to me that the problem must be with HttpUtility.UrlEncode. Have you checked the contents of the xml that you're creating? The XSL looks correct to me, although it could be written more tersely as:
<a href="{#link}" target="new">
<xsl:value-of select="title"/>
</a>