How to make a required field in XSL/XSLT - xslt

I have 3 radio button selection choices, and if the user selects the option "Forward" there is an input field for them to enter an email address. How can I make that input field required if they select the forward radio button? I can't seem to find any good information on XSLT required fields. The code is below:
<table cellpadding="0" id="allCategoryCheckboxes" >
<tr id="categoryRows">
<xsl:for-each select="form/categories/all/category">
<xsl:sort data-type="number" order="ascending"
select="((value='Available') * 1) +
((value='Unavailable') * 2) +
((value='Forward') * 3)"/>
<td>
<input type="radio" name="catUid">
<xsl:attribute name="value"><xsl:value-of select="uid"/></xsl:attribute>
<xsl:if test="uid = ../../current//category/uid"><xsl:attribute name="checked">checked</xsl:attribute></xsl:if>
</input>
<xsl:value-of select="value"/>
<xsl:if test="value = 'Forward'">
<xsl:text> to: </xsl:text>
<xsl:variable name="someEmailAddress">
<xsl:if test="/bedework/formElements/form/xproperties/node()[name()='X-FORWARDING-ADDRESS']">
<xsl:value-of select="/bedework/formElements/form/xproperties/node()[name()='X-FORWARDING-ADDRESS']/values/text"/>
</xsl:if>
</xsl:variable>
<input type="text" name="someEmailForwardingAddress" value="{$someEmailAddress}" id="someEmailForwardingAddress"/>
</xsl:if>
</td>
</xsl:for-each>
</tr>
</table>

Related

XSLT Count using variable and for-each

I am trying to get the count using the for-each and counter variable but I am getting an incorrect values. Any help with this would be great.
XML
<ProjectFileManagers>
<ProjectFileManagers>
<ProjectFileManagerId>34</ProjectFileManagerId>
<ProjectId>39352</ProjectId>
<FileManagerId>11</FileManagerId>
</ProjectFileManagers>
<ProjectFileManagers>
<ProjectFileManagerId>35</ProjectFileManagerId>
<ProjectId>39352</ProjectId>
<FileManagerId>12</FileManagerId>
</ProjectFileManagers>
</ProjectFileManagers>
XSLT
<tr>
<td colspan="5">
<span class="title">
<xsl:text>Material Attached</xsl:text>
</span>
<br />
<xsl:variable name="materialCount" select="0"></xsl:variable>
<xsl:for-each select="ProjectFileManagers/ProjectFileManagers/ProjectFileManagerId">
<xsl:value-of select="$materialCount + 1"/>
</xsl:for-each>
<xsl:value-of select="$materialCount" disable-output-escaping="yes" />
</td>
</tr>
in stead of
<xsl:value-of select="$materialCount + 1"/>
use:
<xsl:value-of select="position()"/>

The variable or parameter 'Rows' is either not defined or it is out of scope

How do i achieve this through xslt?
I am getting an error from the cde above given by you
( sharepoint 2010 xslt dataview : modify table structure to display list item )
The error is: The variable or parameter 'Rows' is either not defined or it is out of scope.
Please help why am i getting this error:(
My full code would go like this after the code by you has been added:
<xsl:template match='dsQueryResponse'>
<table cellpadding="10" cellspacing="0" border="1" style="padding:25px;">
<!--table for head-->
<tr>
<!--table row-->
<td colspan='2'>
<!--table definition-->
<b style="font-size:25px;">ELearning List</b>
<!-- heading-->
</td>
</tr>
<xsl:apply-templates select='Rows/Row'/>
</table>
</xsl:template>
<xsl:template match='Row'>
<!-- template is defined above -->
<xsl:for-each select="$Rows[position() mod 3 = 1]">
<!-- 3 recods in one row should be displayed -->
<tr>
<xsl:variable name="i" select="position() - 1" />
<xsl:for-each select="$Rows[(position() > ($i * 3)) and (position() <= (($i + 1) * 3))]">
<td>
<img src="../PublishingImages/FLDRNEW.GIF" width="50px" height="50px" style="padding-right:20px;"></img>
<!-- image is to display folder below which the hyperlinked text has been populated -->
<br/>
<a href="{#FileRef}" style="font-weight:bold;">
<!-- it is the anchor tag which drives to the corresponding documents -->
<xsl:value-of select="substring-after(string(#FileRef),'/Docs/')"/>
<!-- fetches the value of Name column -->
</a>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</xsl:template>
The error is: The variable or parameter 'Rows' is either not defined or it is out of scope.
Please help
Could you give this a try?
<xsl:template match='dsQueryResponse'>
<table cellpadding="10" cellspacing="0" border="1" style="padding:25px;">
<!--table for head-->
<tr>
<!--table row-->
<td colspan='2'>
<!--table definition-->
<b style="font-size:25px;">ELearning List</b>
<!-- heading-->
</td>
</tr>
<xsl:apply-templates
select='Rows/Row[position() mod 3 = 1]' mode="group" />
</table>
</xsl:template>
<xsl:template match='Row' mode="group">
<tr>
<xsl:apply-templates
select=". | following-sibling::Row[position() < 3]" />
</tr>
</xsl:template>
<xsl:template match="Row">
<td>
<!-- image is to display folder below which the hyperlinked text has
been populated -->
<img src="../PublishingImages/FLDRNEW.GIF" width="50px" height="50px"
style="padding-right:20px;" />
<br/>
<!-- the anchor tag which drives to the corresponding documents -->
<a href="{#FileRef}" style="font-weight:bold;">
<!-- fetches the value of Name column -->
<xsl:value-of select="substring-after(string(#FileRef),'/Docs/')"/>
</a>
</td>
</xsl:template>

How to get the sum of values in attributes in xslt

I am trying to get the sum. Here is the xslt code.
<xsl:template match="Entry">
<xsl:if test="position() <= 10">
<tr>
<td>
<xsl:value-of select="substring-before(#Value,'||')"/>
</td>
<td>
<xsl:value-of select="format-number(substring(substring-after(#Value,'||||'),1,10),'#.#')"/>
</td>
</tr>
</xsl:if>
</xsl:template>
above code will fillter data as two coloums. It is ok. Now I need to get the sum of <xsl:value-of select="format-number(substring(substring-after(#Value,'||||'),1,10),'#.#')"/>
I am from procedural programming. I read many articles but I still coudnt figure out that how to get the sum of this. can anybody help me?
Here is the xml
<TopHoldings Currency="xxx">
<Entry Type="CName||C||S||Fund Weight (%)||Benchmark weight (%)" Value="Ab||U||||1.2170000000000||" Date="8/31/2011" />
here is the whole xslt
<table style="width:50%;font-size:12px;" cellspacing="0" cellpadding="0">
<tr style="width:50%; text-align:left;background-color:E6F1F9;">
<th> </th>
<th> % of funds </th>
</tr>
<xsl:apply-templates select="$items">
<xsl:sort select="format-number(substring(substring-after(#Value,'||||'),1,10),'#.#')" order="descending"/>
<xsl:sort select="substring-before(#Value,'||')"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Entry">
<xsl:if test="position() <= 10">
<tr>
<td>
<xsl:value-of select="substring-before(#Value,'||')"/>
</td>
<td>
<xsl:value-of select="format-number(substring(substring-after(#Value,'||||'),1,10),'#.#')"/>
</td>
</tr>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
When you need to sum the values of multiple values on XSLT 1.0 you have to rely on recursion [EDIT: in XSLT 1.0 the function sum it is also available] (in XSLT 2.0 there is an XPath function sum()).
The following template performs the sum of the given elements through the elements-to-sum parameter, extracting the value to sum from the attribute #Value as you specified.
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" />
<xsl:template match="TopHoldings">
<table>
<xsl:call-template name="sum">
<xsl:with-param name="elements-to-sum"
select="Entry" />
</xsl:call-template>
</table>
</xsl:template>
<xsl:template name="sum">
<xsl:param name="elements-to-sum" />
<xsl:param name="sum" select="'0'" />
<!-- Store in variables the following operations to avoid performing them more than once -->
<xsl:variable name="current-element" select="$elements-to-sum[1]" />
<xsl:variable name="current-value" select="format-number(substring(substring-after($current-element/#Value,'||||'),1,10),'#.#')" />
<!-- Output the table row -->
<tr>
<td><xsl:value-of select="substring-before($current-element/#Value, '||')" /></td>
<td><xsl:value-of select="$current-value" /></td>
</tr>
<!-- Determine whether continue -->
<xsl:choose>
<!-- Case END: we have just one element to sum so we perform the sum and we output the desired result -->
<xsl:when test="count($elements-to-sum) = 1">
<tr>
<td>Result:</td>
<td><xsl:value-of select="$current-value + $sum" /></td>
</tr>
</xsl:when>
<!-- Case RECURSION : we call this template again adding the current value to the sum and removing the first element from the parameter elements-to-sum -->
<xsl:otherwise>
<xsl:call-template name="sum">
<xsl:with-param name="elements-to-sum"
select="$elements-to-sum[position() > 1]" />
<xsl:with-param name="sum"
select="$sum + $current-value" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
I assumed that you wanted to display the result of the sum as a new row in the same table, if that is not the case and you want to display the result elsewhere the solution would be slightly different. Tell me if this solution is acceptable to you or you need to display the sum outside the element.
NOTE: Instead of doing those 'complex' string operations in the attribute #Value, I would consider splitting all the information within that attribute into different attributes.
Just use the XPath function sum(), it is available in both XPath 2.0 for XSLT 2.0 and XPath 1.0 for XSLT 1.0 as described in http://www.w3.org/TR/xpath/#function-sum. If the numbers you want to get the sum of are attributes "Value" to an element "Entry" use sum(//Entry/#Value)" to grab all and sum up. Change this to get the 10 elements you want in your xml data.

Getting an attribute via another attribute in XSL

I stink at XSLT, so I'm not sure how to approach this... I'm getting a feed from the EQ2 database. The XML looks like this:
<guilds limit="1" returned="1">
<guild accounts="3" alignment="0" dateformed="1127855265" guildid="111" guildstatus="0" id="1111111111" last_update="1326986410" level="11" name="MyGuild" version="1" world="Permafrost" worldid="202">
<ranks>
<rank id="0" name="Leader"/>
<rank id="1" name="Senior Officer"/>
<rank id="2" name="Officer"/>
<rank id="3" name="Senior Member"/>
<rank id="4" name="Member"/>
<rank id="5" name="Junior Member"/>
<rank id="6" name="Initiate"/>
<rank id="7" name="Recruit"/>
</ranks>
<members>
<member dbid="123456" rank="0" name="Dude1"/>
<member dbid="123457" rank="1" name="Dude2"/>
<member dbid="123458" rank="2" name="Dude3"/>
<member dbid="123459" rank="4" name="Dude4"/>
<member dbid="123460" rank="4" name="Dude5"/>
<member dbid="123461" rank="4" name="Dude6"/>
</members>
<events/>
</guild>
</guilds>
I'm trying to add the ranks into a table. The XSL (version 1) snippet for it is as follows, but adding the name from the rank isn't working properly - I know this part is wrong:
<xsl:value-of select="rank/rank[#id=1]/#name"/>
So, can I get some help making it work and maybe an idea of how to shorten it?
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" indent="yes"/>
<xsl:template match="/">
<table width="100%" cellspacing="0" cellpadding="0" id="eq2roster" align="center">
<thead>
<tr>
<td colspan="4" class="eq2CharacterHeader">Character</td>
<td colspan="3" class="eq2TradeskillsHeader">Tradeskills</td>
</tr>
<tr class="ForumCategoryHeader">
<th class="eq2NameHeader">Name</th>
<th class="eq2RankHeader">Rank</th>
<th class="eq2ClassHeader">Class</th>
<th class="eq2LevelHeader">Level</th>
<th class="eq2ArtisanHeader">Artisan</th>
<th class="eq2ArtisanLevelHeader">Level</th>
<th class="eq2SecondaryHeader">Secondary</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="guilds/guild/members/member">
<xsl:if test="#id > 1">
<tr>
<td class="eq2Name">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:text>http://eq2players.station.sony.com/</xsl:text>
<xsl:value-of select="concat(normalize-space(/guilds/guild/#world), '/')"/>
<xsl:value-of select="concat(normalize-space(#name), '/')"/>
</xsl:attribute>
<xsl:attribute name="target">
<xsl:text>_blank</xsl:text>
</xsl:attribute>
<xsl:value-of select="normalize-space(#name)"/>
</xsl:element>
</td>
<xsl:element name="td">
<xsl:attribute name="class">
<xsl:text>eq2Rank eq2rank-</xsl:text>
<xsl:value-of select="translate(normalize-space(guild/#rank),' ','')"/>
</xsl:attribute>
<xsl:choose>
<xsl:when test="member/#rank = 1"><span class = "rank1"><xsl:value-of select="ranks/rank[#id=1]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 2"><span class = "rank2"><xsl:value-of select="ranks/rank[#id=2]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 3"><span class = "rank3"><xsl:value-of select="ranks/rank[#id=3]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 4"><span class = "rank4"><xsl:value-of select="ranks/rank[#id=4]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 5"><span class = "rank5"><xsl:value-of select="ranks/rank[#id=5]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 6"><span class = "rank6"><xsl:value-of select="ranks/rank[#id=6]/#name"/></span></xsl:when>
<xsl:when test="member/#rank = 7"><span class = "rank7"><xsl:value-of select="ranks/rank[#id=7]/#name"/></span></xsl:when>
</xsl:choose>
</xsl:element>
<xsl:element name="td">
<xsl:attribute name="class">
<xsl:text>eq2Class eq2</xsl:text>
<xsl:value-of select="translate(normalize-space(type/#class),' ','')"/>
</xsl:attribute>
<xsl:value-of select="type/#class"/>
</xsl:element>
<td class="eq2level"><xsl:value-of select="type/#level"/></td>
<xsl:element name="td">
<xsl:attribute name="class">
<xsl:text>eq2ArtisanClass eq2</xsl:text>
<xsl:value-of select="translate(normalize-space(tradeskills/tradeskill/#class),' ','')"/>
</xsl:attribute>
<xsl:value-of select="tradeskills/tradeskill/#class"/>
</xsl:element>
<td class="eq2ArtisanLevel"><xsl:value-of select="tradeskills/tradeskill/#level"/></td>
<xsl:element name="td">
<xsl:attribute name="class">
<xsl:text>eq2Secondary eq2</xsl:text>
<xsl:value-of select="translate(normalize-space(secondarytradeskills/secondarytradeskill/#name),' ','')"/>
</xsl:attribute>
<xsl:value-of select="secondarytradeskills/secondarytradeskill/#name"/>
</xsl:element>
</tr>
</xsl:if>
</xsl:for-each>
</tbody>
</table>
</xsl:template>
</xsl:stylesheet>
The following expression associates a member with its corresponding rank using current() (assuming that the context node is the member in question):
../../ranks/rank[#id=current()/#rank]/#name
Full example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="member">
<td class="eq2Rank eq2rank-{guild/#rank}">
<span class="rank{#rank}">
<xsl:value-of
select="../../ranks/rank[#id=current()/#rank]/#name"/>
</span>
</td>
</xsl:template>
</xsl:stylesheet>
Output (based on the originally posted sample XML):
<td class="eq2Rank eq2rank-">
<span class="rank0">Leader</span>
</td>
<td class="eq2Rank eq2rank-">
<span class="rank1">Senior Officer</span>
</td>
<td class="eq2Rank eq2rank-">
<span class="rank2">Officer</span>
</td>
<td class="eq2Rank eq2rank-">
<span class="rank4">Member</span>
</td>
<td class="eq2Rank eq2rank-">
<span class="rank4">Member</span>
</td>
<td class="eq2Rank eq2rank-">
<span class="rank4">Member</span>
</td>
Not sure if you can do something like this but it might be worth a shot. In the context of a single member
<xsl:value = "//ranks/rank[#id = ./#rank]/#name"/>
It uses X-Path to jump to the top and look for the ranks node, find the rank element whose ID attribute equals the rank attribute of the member, and grabs the name attribute
It's been a few years since I had to XSL like that, but should allow you to get rid of the XSL:choose block
I'm not really sure if I get the question.
Asume that you have the right rankid you probably want to use variable
<xsl:variable name="rank" select="translate(normalize-space(guild/#rank),' ','')"/>
<span class = "rank{$rank}"><xsl:value-of select="ranks/rank[#id = $rank]/#name"/></span>

XSL only show 10 loops in the for-each

My XML has 100 AgentSales nodes I only want to show the first 10 so far I have
<xsl:for-each select="NewDataSet/AgentSales">
<tr>
<xsl:if test="(position() mod 2 = 1)">
<xsl:attribute name="bgcolor">#cccccc</xsl:attribute>
</xsl:if>
<td>
<span style="font:20px arial; font-weight:bold;">
<xsl:value-of select="AgentName"/>
</span>
</td>
<td>
<span style="font:20px arial; font-weight:bold;">
<xsl:value-of select="State"/>
</span>
</td>
<td>
<span style="font:20px arial; font-weight:bold;">
<xsl:value-of select="time"/>
</span>
</td>
</tr>
</xsl:for-each>
New to the site but when I use the code brackets not all of my code shows? at least not in the preview below.
Use:
<xsl:for-each select="NewDataSet/AgentSales[not(position() >10)]">
<!-- Process each node from the node-list -->
</xsl:for-each>
Even better:
<xsl:apply-templates select="NewDataSet/AgentSales[not(position() >10)]"/>
Try something like:
<xsl:for-each select="NewDataSet/AgentSales">
<xsl:if test="position() <= 10">
...
</xsl:if>
</xsl:for-each>