XSLT Count using variable and for-each - xslt

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()"/>

Related

How to make a required field in XSL/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>

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.

How to get the same behavior like xsl:value-of select in an onclick hyperlink attribute?

I've got an xsl issue, this is the situation:
<td onclick="location.href='/vakman/default.asp?name='" style="cursor:pointer" valign="top" height="100%">
After default.asp?name=' I need this value: <xsl:value-of select="veld[5]" />
Can someone help me with the right notation?
UPDATE
Here's some more of the code I use:
<table border="0" align="right" cellspacing="4" cellpadding="0">
<xsl:for-each select="//regels/item">
<xsl:variable name="coor" select="veld[1]" />
<xsl:variable name="coor1" select="veld[2]" />
<xsl:variable name="naam" select="veld[5]"/>
<xsl:value-of select="xsl:getKop()" disable-output-escaping="yes" />
<td onclick="location.href='/vakman/default.asp?naam='" style="cursor:pointer" valign="top" height="100%">
<table border="0" cellspacing="4" cellpadding="0" class="toppersTable" width="250px" height="75px">
<tr><td>
<b>
<xsl:value-of select="xsl:showOms(string(veld[5]))" />
<xsl:value-of select="xsl:showOms(string(veld[6]))" /></b><br />
<xsl:value-of select="xsl:showOms(string(veld[8]))" /><br />
<xsl:value-of select="xsl:showOms(string(veld[9]))" />
<xsl:value-of select="xsl:showOms(string(veld[10]))" /><br />
<xsl:value-of select="xsl:showOms(string(veld[11]))" />
</td></tr>
</table>
</td>
<xsl:value-of select="xsl:getBottom()" disable-output-escaping="yes" />
<xsl:value-of select="$coor" />
<xsl:value-of select="$coor1" />
</xsl:for-each>
</table>
</table>
Use:
<td onclick="location.href='/vakman/default.asp?name={veld[5]}'"
style="cursor:pointer" valign="top" height="100%">
Explanation: The use of AVT (Attribute Value Templates) is recommended whenever the name of the attribute is statically known. It results in shorter and more readable code.
Try using the xsl:attribute tag. you'll end up with something like this:
<td style="cursor:pointer" valign="top" height="100%">
<xsl:attribute name="onclick">location.href='/vakman/default.asp?name=<xsl:value-of select="veld[5]" />'</xsl:attribute>

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>

XSL checking integer

How to check the integer value in XSL? I'm using version 1.0
This is what I've tried, but it's not working:
<xsl:variable name="ShowEmailEventId"
select="com.zoniac.emailevent.NewEmailEventBean/emailEventIdString"/>
<xsl:if test="$ShowEmailEventId !=48">
<table align="center"
width="96%"
border="1"
style="border-color:#2E73AD;border-collapse:collapse"
cellspacing="0"
cellpadding="10">
<tr>
<td width="10%"
style="border-color:#2E73AD;color: black; font: 11px verdana;padding:2px"
align="left"
valign="top">
<b>S.No</b>
</td>
</tr>
</table>
</xsl:if>
This is probably the shortest expression, returning true() iff $x can be used as an integer:
Just use:
floor($x) = $x
The full test will be:
<xsl:if test="floor($x) = $x">
<!-- $x is an integer -->
</xsl:if>
or
<xsl:when test="floor($x) = $x">
<!-- $x is an integer -->
</xsl:when>
or
someXPathExpression[floor($x) = $x]
TO check if a value nameofint is an int... (you are obviously going to want to change the inside of the if condition.
<xsl:template match="CheckInt">
<xsl:if test="not(string(.) castable as xs:integer)">
<xsl:text>NOT AN INT: </xsl:text>
<xsl:value-of select="."/>
</xsl:if>
</xsl:template>