Truncate decimal places without rounding - xslt

I want to truncate all the decimal places using xslt.
The input and expected values are below.
17.99 -> 17
19.01 -> 19
18.0 -> 18
I used
<xsl:value-of select='format-number(17.99, "0")' />
But it gives 18 for 17.99. That mean, this rounding the number.
How can I change xslt so that output message is populating only with truncating decimal places and without rounding? Could you please anyone guide me?

You can use floor here
<xsl:value-of select='format-number(floor(17.99), "0")' /> <!-- 17 -->
<xsl:value-of select='format-number(floor(19.01), "0")' /> <!-- 19 -->
<xsl:value-of select='format-number(floor(18.0), "0")' /> <!-- 18 -->
In fact, you might not even need the format-number here
<xsl:value-of select='floor(17.99)' /> <!-- 17 -->
<xsl:value-of select='floor(19.01)' /> <!-- 19 -->
<xsl:value-of select='floor(18.0)' /> <!-- 18 -->

Related

how to distinguish <br> inside <h5>?

could you help me with this problem please?
part of input xml:
<h5 class="Paragraf">
§ 113 a 114
<br/>
zrusen
</h5>
what would I like to have on output:
§ 113 a 114 -> A_Header_5
zrusen -> A_Header_5-Podnadpis
part of xslt condition which I created but it’s not doing what I want:
<xsl:when test="(self::h5) and not (child::br)">A_Header_5</xsl:when>
<xsl:when test="(self::h5) and (child::br)">
<xsl:if test="text()[1]">A_Header_5</xsl:if>
<xsl:if test="text()[2]">A_Header_5-Podnadpis</xsl:if>
</xsl:when>
unfortunately output with this xslt conditions looks this:
§ 113 a 114 -> A_Header_5A_Header_5-Podnadpis
zrusen -> A_Header_5A_Header_5-Podnadpis
Thank you
This is not exactly the same logic as in your post, but without a full _ Minimal, Complete, and Verifiable example_ it is hard to spot the root cause of your dissatisfaction with your code.
The following code iterates over all text() nodes and distinguishes on the basis of the existence of a following <BR /> element.
XSLT 1.0:
<xsl:template match="h5">
<xsl:for-each select="text()">
<xsl:if test="."><xsl:value-of disable-output-escaping = "yes" select="concat(normalize-space(.),' -> ')" /></xsl:if>
<xsl:if test="following-sibling::br">A_Header_5</xsl:if>
<xsl:if test="not(following-sibling::br)">A_Header_5-Podnadpis</xsl:if>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
Output:
§ 113 a 114 -> A_Header_5
zrusen -> A_Header_5-Podnadpis

XSLT sort Arabic letters

I have XML like:
<Answers>
<QuestionAnswer Id="1" Answer="أقل من 16 عام"/>
<QuestionAnswer Id="2" Answer="17 – 24 عامً"/>
<QuestionAnswer Id="3" Answer="25- 34 عامً"/>
<QuestionAnswer Id="4" Answer="35- 44 عامً"/>
<QuestionAnswer Id="5" Answer="أكثر من 45 عامً"/>
</Answers>
XSL:
<xsl:for-each select=".//QuestionAnswer">
<xsl:variable name="AnswerId" select="#Id"/>
<xsl:variable name="AnswerText" select="#Answer"/>
<xsl:value-of select="concat(' ',$AnswerId, ' "', $AnswerText, '"')" />
</xsl:for-each>
and return should be the order from XML, but is in an odd order because of Arabic characters.
How can I fix this?
1 "أقل من 16 عام"
2 "17 – 24 عامً"
3 "25- 34 عامً"
4 "35- 44 عامً"
5 "أكثر من 45 عامً"
If you want to sort on the value of #Answer then you should be able to use
<xsl:for-each select=".//QuestionAnswer">
<xsl:sort select="#Answer" lang="ar"/>
You can further qualify the language code, e.g. lang="ar-EG" gives sorting according to the rules for Arabic as used in Egypt. I don't know anything about Arabic so I don't know if this is necessary.
Of course, it might be that your XSLT processor does not support all possible language codes.
Try adding the RTL unicode to your sentence:
<xsl:variable name="rightToLeftUnicode" select="'‎'"></xsl:variable>
<xsl:value-of select="concat(' ',$AnswerId, ' "', $AnswerText, '"', $rightToLeftUnicode)" />

xsl - format-number from one to two digits 1 => 01

is there in XSLT some function or somethg to alow format digits
like eg 1 will become 01
so if I have
<a>10</a>
<b>5</b>
they will apear as
A10
and
B05
Function Formating numbers:
<xsl:template match="root/*">
<xsl:value-of select="format-number(.,'00')"/>
</xsl:template>
XSLT 1.0 uppercase of nodenames:
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:value-of select="translate(name(), $smallcase, $uppercase)" />
Combined:
<xsl:value-of select="concat(translate(name(), $smallcase, $uppercase), format-number(.,'00'))" />
format-number(5, '00')
returns "05".
Similarly,
format-number(10, '00')
returns "10".

How can I trim a decimal value to four places behind the decimal point using XSLT

In my ORACLE SOA BPEL process, we are receiving a value as string # 10.2345678956 but for target system we just need to send upto 4 places in decimal like 10.2345. Could you please tell me how we can achieve that using xslt.
also if source system send value as 10 even those in that case, to target system we need to send 10.0000(always 4 digit in decimal)
To truncate (i.e. round down) a number to 4 decimal digits precision, you can do:
floor($number * 10000) div 10000
To format the result to always display 4 decimal digits:
format-number(floor($number * 10000) div 10000, '0.0000')
This works in XSLT 1.0 and XSLT 2.0 alike.
If you don't care about the direction of rounding, then do simply:
format-number($number, '0.0000')
and be done with it.
You don't specify which version of XSLT you are using, but in XSLT 1.0 you should do this "by hand", like as follows:
Note: as Michael says in the comments, you can use format-number in XSLT 1.0. However, the chosen rounding is unclear. While this works, see Michael's answer for a more trivial solution.
<xsl:template match="/">
<xsl:variable name="input" select="10.23456789" />
<xsl:call-template name="truncate">
<xsl:with-param name="val" select="$input" />
</xsl:call-template>
</xsl:template>
<xsl:template name="truncate">
<xsl:param name="val" />
<xsl:variable name="adj">
<xsl:value-of select="$val"/>
<xsl:if test="not(contains($val, '.'))">.</xsl:if>
<xsl:text>0000</xsl:text>
</xsl:variable>
<xsl:variable name="before" select="substring-before($adj, '.')" />
<xsl:variable name="after" select="substring-after($adj, '.')" />
<xsl:value-of select="$before" />
<xsl:text>.</xsl:text>
<xsl:value-of select="substring($after, 1, 4)" />
</xsl:template>
And in XSLT 2.0 and 3.0, you can simply do as follows:
<xsl:value-of select="format-number($input, '#.0000')" />
But this will round up (halves to even), i.e. with your input it would give you 10.2346. If that is undesirable, you could use the trick suggested by fvu:
<xsl:value-of select="
format-number(xs:integer(number($input) * 10000) div 10000, '#.0000')" />
Both the XSLT 1.0 and XSLT 2.0/3.0 versions above will append the necessary zeroes up to four.

XSL if column X is character X the do this else do that

-XSL Version 1.0 -
I have an XSL file that was created by someone that no longer works at my company and of course we need to change the XSL. I have never used XSL but did some searching and believe I can perform the function needed by updating the XSL with a choose function.
-Issue-
We have a field that was changed from a leading character count of 13 to 11 but we need to capture both for some time period. It was decided to trim the two leading characters of the year. The values will remain constant up to the slash "/" at either 13 or 11 characters, characters after can vary from 5-13 characters.
13 characters CTM08G2012001/0001
11 characters CTM08G12001/0001
I want to check to see if the 12th character is a "/" and if it is use the first 11 characters and if it is not use the first 13 characters. Here is the code for the function.
Where would I put the choose/otherwise function? There appears to be several that repeat themselves and this confuses me.
How do I capture the "/" in the specific string?
I will continue to research and do apologize for not having a list of things tried as I am not sure where to even start.
<func:function name="func:getProjClaimNo">
<xsl:param name='Proj' />
<xsl:param name='Claim' />
<xsl:variable name="isNUMB" select="'1234567890'"/>
<xsl:variable name="vProj1" select="substring($Proj, 8, 1)"/>
<xsl:variable name="vProj2" select="substring($Proj, 9, 1)"/>
<xsl:choose> <!-- 1 -->
<xsl:when test="contains($isNUMB,$vProj1)"> <!-- 1 -->
<xsl:choose> <!-- 2 -->
<xsl:when test="contains($isNUMB,$vProj2)"> <!-- 2 -->
<xsl:variable name="vProj3" select="number(substring($Proj, 8, 2))"/>
<xsl:choose> <!-- 3 -->
<xsl:when test="$vProj3 > 8"> <!-- 3 -->
<func:result select="$Proj"/>
</xsl:when> <!-- 3 -->
<xsl:otherwise> <!-- 3 -->
<!-- May need to check to see if claim number is empty or if proj in table -->
<xsl:choose>
<!-- 4 -->
<xsl:when test="$Claim=''"> <!-- 4 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:when> <!-- 4 -->
<xsl:otherwise> <!-- 4 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:otherwise> <!-- 4 -->
</xsl:choose> <!-- 4 -->
</xsl:otherwise> <!-- 3 -->
</xsl:choose> <!-- 3 -->
</xsl:when> <!-- 2 -->
<xsl:otherwise> <!-- 2 -->
<!-- May need to check to see if claim number is empty -->
<xsl:choose> <!-- 5 -->
<xsl:when test="$Claim=''"> <!-- 5 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:when> <!-- 5 -->
<xsl:otherwise> <!-- 5 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:otherwise> <!-- 5 -->
</xsl:choose> <!-- 5 -->
</xsl:otherwise> <!-- 2 -->
</xsl:choose> <!-- 2 -->
</xsl:when> <!-- 1 -->
<xsl:otherwise> <!-- 1 -->
<!-- May need to check to see if claim number is empty -->
<xsl:choose> <!-- 6 -->
<xsl:when test="$Claim=''"> <!-- 6 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:when> <!-- 6 -->
<xsl:otherwise> <!-- 6 -->
<func:result select="substring($Claim, 1, 13)"/>
</xsl:otherwise> <!-- 6 -->
</xsl:choose> <!-- 6 -->
</xsl:otherwise> <!-- 1 -->
</xsl:choose> <!-- 1 -->
</func:function>
I don't see where that "field" is in your stylesheet snippet. In general, you can do something like this:
<xsl:choose>
<xsl:when test="substring($yourfield, 12, 1) ='/'">
<xsl:value-of select="substring($yourfield, 1, 11)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring($yourfield, 1, 13)"/>
</xsl:otherwise>
</xsl:choose>
or, more succinctly:
<xsl:value-of select="substring($yourfield, 1, 13-2*(substring($yourfield, 12, 1) ='/'))"/>
However, If I understand correctly, it could be much simpler:
<xsl:value-of select="substring-before($yourfield, '/')"/>