change the class of a link with xslt - xslt

I would like to change the class of a link but something must be wrong, however I can't see where.
I have checked that the if test is OK.
Could you tell me where I was wrong ?
<xsl:template match="*" mode="title-link-proced">
<a target="BodyPart" class="little_link">
<xsl:if test="#change = 'true'">
<xsl:attribute name="class">little_link_evolution</xsl:attribute>
</xsl:if>
</a>
</xsl>
I also tried
<xsl:template match="*" mode="title-link-proced">
<a target="BodyPart" class="little_link">
<xsl:if test="#change = 'true'">
<xsl:attribute name="class" select="little_link_evolution"></xsl:attribute>
</xsl:if>
</a>
</xsl>
but that dit not work either
EDIT:
I checked that there is a change attribute with the value true (if I display:
<xsl:value-of select="#change"/>
I get true)
EDIT 2
XML iput
<level_4 change="true" module="2X3E-ZE_RTY_OAD" title="presentation">
</level_4>

OK, it might help some one day
rather than attemting to modify the existing class, I decide not to attribute a class in the beginning and to do this:
<a target="BodyPart">
<xsl:choose>
<xsl:when test="#change = 'true'">
<xsl:attribute name="class">little_link_evolution</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="class">little_link</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
And it worked !

Related

XSLT determining if a parameter is null or empty then do something

I'm trying to determine if ../../coupon_code is null or empty. I've tried the methods in this thread Check if a string is null or empty in XSLT to no avail. Maybe I'm doing something wrong?
<!--Coupon Code Name and Code-->
<xsl:choose>
<xsl:when test="not(../../coupon_code)">
<xsl:if test="../../coupon_code != ''">
<xsl:value-of select="../../coupon_rule_name" /> <xsl:value-of select="../../coupon_code" /><xsl:value-of select="$sepend" />D.PROMOTION<xsl:value-of select="$sepend" />
</xsl:if>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
<!--End Coupon Code Name and Code-->
I'm doing
<xsl:when test="not(../../coupon_code)">
To determine if it's null. Then, I'm doing
<xsl:if test="../../coupon_code != ''">
To determine if it's empty.
However, I'm looking at data where this is clearly populated, and it's not entering the when/if to display the data at all. So it's failing somewhere and I don't know where.
Sometimes, ../../coupon_code will have a coupon code in it, like COUPON122. Sometimes it won't have anything in it.
You can check
<xsl:if test="normalize-space(../../coupon_code)">
<xsl:value-of select="../../coupon_rule_name" /> <xsl:value-of select="../../coupon_code" /><xsl:value-of select="$sepend" />D.PROMOTION<xsl:value-of select="$sepend" />
</xsl:if>
to have the xsl:value-ofs processed only if the ../../coupon_code element has some non-whitespace content.

Add link in author label - DSpace 6.2

I've trying to edit item-view.xsl to add a link in author label (dc.contributor.author) but no luck yet.
I'm using XMLUI - Mirage2
Author link example image
in: https://openknowledge.worldbank.org/handle/10986/29498
What should I add?
Thanks
The following code snippet might help. This code turns the subject field into a facet link. It will require a little modification to work for the author field.
<xsl:variable name="H_SUBJECT">Subject</xsl:variable>
<xsl:variable name="DFILTER_SUBJECT">/discover?filtertype=subject&filter_relational_operator=equals&filter=</xsl:variable>
<xsl:template name="itemSummaryView-DIM-subject">
<xsl:if test="dim:field[#element='subject']">
<div class="simple-item-view-description item-page-field-wrapper table">
<h5><xsl:value-of select="$H_SUBJECT"/></h5>
<div>
<xsl:for-each select="dim:field[#element='subject']">
<xsl:choose>
<xsl:when test="node()">
<a class="gu-subject-link" href="{concat($FILTER_SUBJECT,.)}">
<span>
<xsl:apply-templates select="." mode="microtag-prop"/>
<xsl:apply-templates select="text()"/>
</span>
</a>
</xsl:when>
<xsl:otherwise>
<xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="count(following-sibling::dim:field[#element='subject']) != 0">
<xsl:text>; </xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:if test="count(dim:field[#element='subject']) > 1">
<xsl:text>; </xsl:text>
</xsl:if>
</div>
</div>
</xsl:if>
</xsl:template>

How to conditionally output tags?

Tags can be outputted by either directly typing
<div>
<span>complex...</span>
</div>
or using <xsl:element>,
<xsl:element name="div">
<span>complex...</span>
</xsl:element>
My question is how to do this: when x, output <div>, when y, output <a>, when z, output no tag?
One of course can make three templates, or even write ugly code as
<xsl:when ...x >
<![CDATA[ <div> ]]>
</xsl:when>
<span>complex...</span>
<xsl:when ...x >
<![CDATA[ </div> ]]>
</xsl:when>
but is there a way to conditionally provide the value of the name attribute of xsl:element?
I tried this, failed:
<xsl:variable name="a" select="'div'"/>
<xsl:element name="$a">
...
[edited] Forgot to say, XSLT1.0 only
Here's another way to look at it:
<xsl:variable name="content">
<span>complex...</span>
</xsl:variable>
<xsl:choose>
<xsl:when ... x>
<div>
<xsl:copy-of select="$content"/>
</div>
</xsl:when>
<xsl:when ... y>
<a>
<xsl:copy-of select="$content"/>
</a>
</xsl:when>
<xsl:when ... z>
<xsl:copy-of select="$content"/>
</xsl:when>
</xsl:choose>
The name attribute is not expecting a full-fledge XPath expression but simply a string. So, instead of using name="$a" you only have to evaluate the Xpath expression into a string by bracing it with curly braces:
<xsl:element name="{$a}">
As for the conditional creation of the surrounding tag you could do something like this:
<xsl:variable name="tag_name">
<xsl:choose>
<xsl:when test="x">
<xsl:text>div</xsl:text>
</xsl:when>
<xsl:when test="y">
<xsl:text>a</xsl:text>
</xsl:when>
</xsl:choose>
<!-- possibly other checks for different tag names -->
<xsl:variable>
<xsl:choose>
<xsl:when test="$tag_name != ''">
<xsl:element name="$tag_name">
<!-- whatever has to be put into a tagged block (A) -->
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- whatever has to be put into a untagged block (B) -->
</xsl:otherwise>
</xsl:choose>
If A and B are equal you could put that into a template.
XSLT doesn't output tags: it outputs nodes to a result tree. Your suggestion of using constructs like <![CDATA[ </div> ]]> is therefore way off the mark: you can't add half a node to a tree.
However, there's no difficulty with conditional generation of elements nodes. If you want to create an element but compute its name conditionally, then in XSLT 2.0 you can do
<xsl:element name="{if (test) then 'a' else 'b'}">
or if you're stuck with 1.0, the much more verbose
<xsl:variable name="elname">
<xsl:choose>
<xsl:when test="test">a</xsl:when>
<xsl:otherwise>b</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$elname}"/>
If you want to output an element or nothing depending on a condition, just do
<xsl:if test="test2">
<e/>
</xsl:if>

XSL Sorting With Sitecore

I'm not very familiar with xsl, so I'm sort of stumbling my way though this.
My xsl file is building a menu. I am trying to sort the menu items by the value in menu title field in Sitecore. When I run the code, it does not sort. It just writes out each menu item four times.
Can anyone shed some light on what I am missing?
<xsl:template name="show-title">
<xsl:param name="root" />
<xsl:for-each select="$sc_currentitem/item">
<xsl:sort select="sc:fld('menu title',.)" order="ascending"/>
<xsl:choose>
<xsl:when test="sc:fld('menu title',$root)!=''">
<sc:text field="menu title" select="$root" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$root/#name" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
EDIT: Below is the data that the code above is generating
Example Output:
03/05/201203/05/201203/05/201203/05/2012
03/01/201203/01/201203/01/201203/01/2012
03/08/201203/08/201203/08/201203/08/2012
03/02/201203/02/201203/02/201203/02/2012
03/07/201203/07/201203/07/201203/07/2012
I am trying to get it to generate the following:
03/01/2012
03/02/2012
03/05/2012
03/07/2012
03/08/2012
Thanks!
It looks like you are trying to read menu title field from the wrong node. You should be reading it from context node --> . <--
Try this
<xsl:template name="show-title">
<xsl:param name="root" />
<xsl:for-each select="$sc_currentitem/item">
<xsl:sort select="sc:fld('menu title',.)" order="ascending"/>
<xsl:choose>
<xsl:when test="sc:fld('menu title',$root)!=''">
<sc:text field="menu title" select="." />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="./#name" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
This is just a guess as you don't really supply enough information for anyone to do more than guess but....
Within your for-each you are referring to $root e.g. <xsl:value-of select="$root/#name" />
I am guessing that the $root parameter contains a list of some kind and that you should be selecting just part of this list based on some value from the current for-each context

Display different xsl:attribute depending on the ending of a string

I have the following xsl code in an xsl document
<A target="_blank" style="text-decoration=none">
<xsl:attribute name="href">viewdoc.aspx?doc=<xsl:value-of select="URLFilePath"/>&mode=inline</xsl:attribute>
<xsl:attribute name="prefix"><xsl:value-of select="FileName"/>: </xsl:attribute>
<IMG src="images/word_small.gif" border="0"/>
</A>
and in the code-behind I am doing this
newItemNode = xmlDocument.CreateElement("URLFilePath")
newItemNode.InnerText = correctedPath
xmlItemNode.ParentNode.AppendChild(newItemNode)
Now that works fine for word documents. However I need a way in code to check the extension of the file, and display the correct Image and xsl:attribute depending on the If statement.
So the If statement will be like this:-
If correctedPath.ToLower.Contains(".doc") Then
//display the word icon and attributes
Else
//display the excel icon and attributes
End If
Can you please give me some tips and help on how I can achieve this?
Thanks
Just using contains() may generally produce the wrong results (see the test XML document).
What is necessary is a ends-with() function, which is standard in XPath 2.0 and can be implemented in XSLT 1.0 as in the following transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="URLFilePath">
<xsl:variable name="visDoc">
<xsl:call-template name="ends-with">
<xsl:with-param name="pEnding" select="'.doc'"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="visXls">
<xsl:call-template name="ends-with">
<xsl:with-param name="pEnding" select="'.xls'"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="$visDoc=1">word_small.gif</xsl:when>
<xsl:when test="$visXls=1">xls_small.gif</xsl:when>
<xsl:otherwise>unknown_small.gif</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="ends-with">
<xsl:param name="pEnding"/>
<xsl:value-of select=
"number(substring(.,
string-length() -string-length($pEnding) +1
)
=
$pEnding
)
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following test XML document:
<files>
<URLFilePath>myFile.doc</URLFilePath>
<URLFilePath>myFile.xls</URLFilePath>
<URLFilePath>myFile.xls.doc</URLFilePath>
<URLFilePath>myFile.doc.xls</URLFilePath>
</files>
the correct result is produced:
word_small.gif
xls_small.gif
word_small.gif
xls_small.gif
Do note that just using contains() produces incorrect results.
I managed to come up with a solution! Sorry for the late reply but had to work on something else
Here is the code:-
<A target="_blank" style="text-decoration=none">
<xsl:choose>
<xsl:when test="contains(., '.doc')">
<xsl:attribute name="href">viewdoc.aspx?doc=<xsl:value-of select="URLFilePath"/>&mode=inline
</xsl:attribute>
<xsl:attribute name="prefix">
<xsl:value-of select="FileName"/>:
</xsl:attribute>
<IMG src="images/word_small.gif" border="0"/>
</xsl:when>
<xsl:when test="contains(., '.xls')">
<xsl:attribute name="href">viewxls.aspx?doc=<xsl:value-of select="URLFilePath"/>&mode=inline
</xsl:attribute>
<xsl:attribute name="prefix">
<xsl:value-of select="FileName"/>:
</xsl:attribute>
<IMG src="images/excel_small.gif" border="0"/>
</xsl:when>
</xsl:choose>
</A>
Thanks for all your help guys, really very much appreciated!
A late reply but I hit to two answers that deal with matching end of string with XSLT 1.0 and are very elegant:
https://stackoverflow.com/a/3081205/520567
https://stackoverflow.com/a/3081866/520567
go give them +1
This can be done purely in your XSLT document if you require. For displaying the image, you could use a xsl:choose statement, that tests the URLFilePath element
<xsl:choose>
<xsl:when test="contains(., '.doc')">
<IMG src="images/word_small.gif" border="0"/>
</xsl:when>
<xsl:when test="contains(., '.xls')">
<IMG src="images/excel_small.gif" border="0"/>
</xsl:when>
</xsl:choose>
If you wanted to do this check in the code behind, you could always add extra attributes to your URLFilePath element.
imageAttr = xmlDocument.CreateAttr("image")
If correctedPath.ToLower.Contains(".doc") Then
imageAttr.value = "images/word_small.gif"
Else
imageAttr.value = "images/excel_small.gif"
End If
newItemNode.AppendChild(imageAttr)
And then, in your xls, you can simply use this attribute to set the source attribute of the image
<IMG border="0">
<xsl:attribute name="src"><xsl:value-of select='#image' /></xsl:attribute>
</IMG>