I need to store the 2 places after decimal (currency amount, so need only upto 2 places) in an XSL variable before I do a ceil function.
<xsl:element name="BaseFare"><xsl:value-of select="ceiling(BaseAmount/Amount * (1 - ($promoDisc div 100)))"/></xsl:element>
For eg. if the result of the Amount is 499 and promoDisc = 8%, then the discounted Amount would be 459.08 - I need to store "08" (with the zero) in a variable for use later, while I return the ceiling amount (460) in the output XML. Thought I could just do a string function and read 2 chars after the decimal into a variable rather than do any math?
There are different ways to do this extraction:
I. Using the string representation of the number:
concat('.',substring(substring-after($x, '.'), 1, 2))
II. Using standard math functions:
$x - floor($x)
This evaluates to the decimal part of any positive number $x.
Use one of the functions: format-number(), round(), round-half-to-even() (the last function available only XPath 2.0 / XSLT 2.0) to round it to two decimal places.
In XSLT 1.0 one way to get from a positive number exactly the digits in the two decimal places after the decimal point (truncate without rounding), is:
format-number(
floor(100* $x) div 100
-
floor(floor(100* $x) div 100),
'.00'
)
Here is a complete example of the described methods:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:value-of select=
"concat('.',substring(substring-after(0.12543, '.'), 1, 2))"/>
=========
<xsl:value-of select=
"format-number(0.12543, '.00')"/>
=========
<xsl:value-of select=
"format-number(
floor(100* 999.12543) div 100
-
floor(floor(100* 999.12543) div 100),
'.00'
)
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on any XML document (not used), the result is:
.12
=========
.13
=========
.12
Related
I use xslt to substring before:
<xsl:element name="mapcat">
<xsl:value-of select="substring-before(categories,'/')"/>
</xsl:element>
Original:
17845/288323/8844
Result:
17845
Working correct
Now I need substring after 10 characters.
I try:
<xsl:element name="mapcat">
<xsl:value-of select="substring(categories,'1,10')"/>
</xsl:element>
But something went wrong and no working. Can anyone help me correct this code?
I need substring after 10 characters.
I am guessing you want to do:
<xsl:value-of select="substring(original-string, 11)"/>
Your explanation of the problem wasn't very clear (difficulties with your English perhaps?) but from the example supplied as a comment you want the first 11 characters of the string, which is substring(xx, 1, 11). Supplying 0 (or anything less than 1) as the second argument has the same effect: the actual semantics of substring(x, a, b) are to include all characters in x whose position p (counting from 1) satisfies p>=a and p<(a+b) -- with additional rules for rounding if the values are not integers.
current Output
<wd:GradeCode>CH_Service_Fly_test worker</wd:GradeCode>
<wd:GradeCode>CN_Dips_12 Engineer depart</wd:GradeCode>
Output needed
<wd:GradeCode>Service_Fl</wd:GradeCode>
<wd:GradeCode>Dips_12 En</wd:GradeCode>
Unfortunately little input. Which could probably work, would be the following function (depending on what you have in mind):
<!-- build a string after the first underline -->
<xsl:variable name="firstString">
<xsl:value-of select="substring-after(., '_')"/>
</xsl:variable>
<!-- limit the firstString to 10 digits -->
<xsl:value-of select="substring($firstString/text(),1,10)"/>
The pending to use for each item.
Is there a way to substring my value 6 places after decimal?
So if I have
<xsl:value-of select="100.1234567890" />
Is there a way to make it
"100.123456"
Your value is a number, not a string. The easy way to trim it to 6 decimal places is to floor it, not substring it:
<xsl:value-of select="floor(100.1234567890 * 1000000) div 1000000"/>
returns:
100.123456
To achieve the same thing through string manipulation, you could do:
<xsl:variable name="n" select="'100.1234567890'" />
<xsl:value-of select="substring($n, 1, string-length(substring-before($n, '.')) + 7)"/>
problem is with specified input, I have an input in which is something like this, -0.982983928391353
and i want to format that to -0.98298 ( upto 5 decimal points) this is the sample input xml below.
<rs>
<R>
<C0>vo</C0>
<C1>f_item</C1>
<C2>1</C2>
<C3>4</C3>
<C4>Stores</C4>
<C5>2011-10-13T00:00:00</C5>
<C6>Active</C6>
<C7>Supplier</C7>
</R>
<R>
<C0>SManufacturing</C0>
<C1>KB18759</C1>
<C2>-0.1002345678907564</C2>
<C3>2</C3>
<C4>Stores</C4>
<C5>1999-02-03T00:00:00</C5>
<C6>Active</C6>
<C7>Supplier</C7>
</R>
</rs>
the required output is
<rs>
<R>
<C0>vo</C0>
<C1>f_item</C1>
<C2>1.00000</C2>
<C3>4.00000</C3>
<C4>Stores</C4>
<C5>2011-10-13T00:00:00</C5>
<C6>Active</C6>
<C7>Supplier</C7>
</R>
<R>
<C0>SManufacturing</C0>
<C1>KB18759</C1>
<C2>-0.10023</C2>
<C3>2.00000</C3>
<C4>Stores</C4>
<C5>1999-02-03T00:00:00</C5>
<C6>Active</C6>
<C7>Supplier</C7>
</R>
</rs>
I tried with this, but this works for positive integers only. It doesn format -0.1002345678907564..
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="#*| node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match = "*[not(*)][translate(.,'0123456789.*****', '') = '']">
<xsl:copy>
<xsl:value-of select="format-number(number(.), '0.00000')"/>
</xsl:copy>
I think you don't understand the use of translate(). The second argument is a key string of individual characters, duplicating the * is irrelevant. The third argument is a string of corresponding translation characters, of which you have none, so it is simply removing the characters from the input. Your test, even with the addition of -, would accept the string "123-45.678.9" as a number.
It is not a pattern matcher, which is implied by your post.
If you want to check in XSLT 1.0 that an element has no child elements and is numeric, this should work:
match="*[not(*)][number(.)=number(.)]"
... which works on the principle that NaN is not equal to NaN.
'0123456789.*****' is missing -.
My request is as below . The EmpNumberList will have 250 EmpNumbers separated by space.
<soapenv:Body>
<v1:MRRequestParam>
<v1:EmpNumberList><v1:EmpNumber> 9989071005 2004421004</v1:EmpNumber></v1:EmpNumberList>
</v1:MRRequestParam>
</soapenv:Body>
The XSLT I need to write should count the EmpNumbers from the EmpNumbersList
I need to call stored procedure in my XSLT such that i make 5 calls .
In one call I pass only 50 EmpNumbers.
I make 5 calls in total
First Call will have $EmpNumber1 such that it contains 50 EmpNumbers
$EmpNumber1 = 9989071005 2004421004 (so on 50 EmpNumbers)
<argument type="SQL_VARCHAR" mode="INPUT" nullable="true" precision="0" scale="0" isNull="false"><xsl:value-of select="$EmpNumber1" />
</argument>
When I send back the response I need to club all 5 result set and send at a time.
Please let me know if you have any suggestions
This one is easy:
Use:
string-length(translate(normalize-space(/*/*/*/v1:EmpNumber), '0123456789',''))+1
When applied on this document (the provided one with one more number):
<soapenv:Body xmlns:soapenv="my:soapenv">
<v1:MRRequestParam xmlns:v1="my:v1">
<v1:EmpNumberList>
<v1:EmpNumber> 9989071005 2004421004 1234567890 </v1:EmpNumber>
</v1:EmpNumberList>
</v1:MRRequestParam>
</soapenv:Body>
the wanted, correct result is returned:
3
Here is a complete XSLT 1.0 stylesheet to run and verify that the correct results are always produced:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="my:soapenv" xmlns:v1="my:v1">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select=
"string-length(
translate(normalize-space(/*/*/*/v1:EmpNumber), '0123456789','')
)+1"/>
</xsl:template>
</xsl:stylesheet>
Do note: You have to specify the correct namespaces in the transformation and in the XML document -- you haven't provided them in your question.
Explanation:
The meaning of this expression:
string-length(
translate(normalize-space(/*/*/*/v1:EmpNumber), '0123456789','')
)+1
is:
normalize-space() . This takes the string and produces a new string from it, in which all leading and trailing whitespace characters are deleted.
What remains are only the numbers with just one intermediate space character between every two numbers. So, if there are N numbers, the number of spaces is N-1.
The translate() function as referenced in the expression, returns a new string in which all digits are gone (replaced by the empty string ''. What remains are only the space characters.
Using the string-length() function we simply get the count of those spaces** (N-1). We add 1 and get the number N of all the numbers in the string.