exponential notation to integer notation XSLT2.0 - xslt

IS it possible to change the following exponential notation to integer notation using XSLT 2.0.
2.0151109001E10
to
20151109001
I tried with
number(2.0151109001E10)
but it gives NaN as answer.
EDIT:
XSLT:
<xsl:variable name="a" select="ss:Cell[$key]/ss:Data"/>
<xsl:variable name="b" select="string($a)"/>
<xsl:variable name="c" select="number($b)"/>
OUTPUT:
<a>2.0151109001E10</a>
<b>2.0151109001E10</b>
<c>2.0151109001E10</c>
The following works out
<xsl:value-of select="xs:decimal(xs:double(translate($a, ',', '.')))"/>

The real problem with your input is not the exponential notation, but the use of a comma as the decimal mark. XML only recognizes a period as the decimal mark.
Try something like:
<xsl:value-of select="xs:decimal(xs:double(translate($a, ',', '.')))"/>
or:
<xsl:value-of select="format-number(translate($a, ',', '.'), '0')"/>

You can try to put them inside the single quotes '' like this:
number('7.2345E7')
gives
72340000

You can use format-number:
format-number(2.0151109001E10, '#')

Related

I would like to include apostrophe in the output attributes

I wrote a code to eradicate all the special characters with a function.
<xsl:function name="lancet:stripSpecialChars">
<xsl:param name="string" />
<xsl:variable name="AllowedSymbols"
select="'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'"/>
<xsl:value-of select="
translate(
$string,
translate($string, $AllowedSymbols, ' '),
' ')
"/>
</xsl:function>
<xsd:element xtt:fixedLength="14" xtt:required="true" xtt:severity="error" xtt:align="left">
<xsl:value-of select="lancet:stripSpecialChars(upper-case(replace(normalize-unicode(translate($emp/wd:First_Name, ',', ' '), 'NFKD'), '⁄', '/')))"/>
</xsd:element>
Now there is a requirement for me to include apostrophe ('). When I am trying to include the same in AllowedSymbols, I am getting an error.
The output Right now is D AGOSTINO. I need something like D'AGOSTINO.
Not sure how to handle this. Could someone please help me out with this. Thanks
You don't say what the error is, but you probably just need to escape the apostrophe in your variable.
This is done by doubling up the apostrophe:
<xsl:variable name="AllowedSymbols" select="'''ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'"/>
Since you're using XSLT 2.0, you should be able to use replace() instead of translate()...
<xsl:function name="lancet:stripSpecialChars">
<xsl:param name="string"/>
<xsl:value-of select="replace($string,'[^A-Z0-9'']','')"/>
</xsl:function>
I'm not replacing lowercase letters since the string you're passing is already forced to uppercase, but if you use the function elsewhere you can add a-z to the character class.
Encode it as &apos; (’ also)
Enclose the value in a CDATA section (recommended as you get rid of encoding problems.
<data><![CDATA[some stuff including D'Agostino & other reserved/problematic characters :-) ]]></data>

I want to get the output with 2 decimal numbers

<xsl:value-of select="format-number(xs:Position/xs:Weekly_Hours,'##.##')"/>
So if I give it as above, its showing it cannot convert string to integer.
I tried this also , but same
<xsl:variable name="myVar" select="xs:Position/xs:Weekly_Hours"/>
<xsl:value-of select="format-number($myVar,'##.##')"/>
Use <xsl:value-of select="format-number(number(xs:Position/xs:Weekly_Hours),'##.##')"/> or if you use XSLT 2.0 or later, instead of number you can use another numeric type like xs:double or xs:decimal.

How do I convert strings starting with numbers to numeric data in XSLT?

Given the following XML:
<table>
<col width="12pt"/>
<col width="24pt"/>
<col width="12pt"/>
<col width="48pt"/>
</table>
How can I convert the width attributes to numeric values that can be used in mathematical expressions? So far, I have used substring-before to do this. Here is an example template (XSLT 2.0 only) that shows how to sum the values:
<xsl:template match="table">
<xsl:text>Col sum: </xsl:text>
<xsl:value-of select="sum(
for $w
in col/#width
return number(substring-before($w, 'pt'))
)"/>
</xsl:template>
Now my questions:
Is there a more efficient way to do the conversion than substring-before?
What if I don't know the text after the numbers? Any way to do it without using regular expressions?
This is horrible, but depending on just how much you know about the potetntial set of non-numeric characters, you could strip them with translate():
translate("12jfksjkdfjskdfj", "abcdefghijklmnopqrstuvwxyz", "")
returns
"12"
which you can then pass to number() as currently.
(I said it was horrible. Note that translate() is case sensitive, too)
I found this answer from Dimitre Novatchev that provides a very clever XPATH solution that doesn't use regex:
translate(., translate(.,'0123456789', ''), '')
It uses the nested translate to strip all the numbers from the string, which yields all other characters, which are used as the values for the wrapping translate function to strip out and return just the number characters.
Applied to your template:
<xsl:template match="table">
<xsl:text>Col sum: </xsl:text>
<xsl:value-of select="sum(
for $w
in col/#width
return number(translate($w, translate($w,'0123456789', ''), ''))
)"/>
</xsl:template>
If you are using XSLT 2.0 is there a reason why you want to avoid using regex?
The most simple solution would probably be to use the replace function with a regex pattern to match on any non-numeric character and replace with empty string.:
replace($w,'[^0-9]','')

Prevent whitespaces between two XSLT-elements from being removed by the xslt-processor

my question is a bit different from the other ones..
i got an xsl-code like this:
<xsl:value-of select="..."/> <xsl:value-of select="...">
what i want in my result is:
result_of_select_1 result_of_select_2
what i get is:
result_of_select_1result_of_select_2
how can i prevent this? ( any xsl:output option for example? )
All the other solutions i found were specificly for the same problem but in the XML-Source document and not in the XSLT-document like this one...
btw. a solution like "insert elements instead of the spaces" is not a possible solution for my, because the xslt-code is generated dynamically
thanks in advance
The white space as you have it is insignificant and gets discarded. If that was not the case, every last bit of white space you have in your XSLT code would end up in the result document. You must be explicit about the white space you want in the result.
User either:
<xsl:value-of select="concat(..., ' ', ...)" />
or:
<xsl:value-of select="..." />
<xsl:text> </xsl:text>
<xsl:value-of select="..." />
Use:
<xsl:value-of select="..."/><xsl:text> </xsl:text><xsl:value-of select="...">
EDIT:
Refer to this ASCII table for other symbols

XSL - Invalid Xpath Extension on Replace

Im getting on error when I try and use the following:
<xsl:variable name="url" select="guid"/>
<xsl:variable name="vid" select="substring-after($url,'podcast/')"/>
<xsl:variable name="pre" select="substring-before($vid,'.mp4')"/>
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
<xsl:variable name="p1" select="concat($p,'.embed_thumbnail.jpg')"/>
<xsl:variable name="p2" select="concat('http://images.ted.com/images/ted/tedindex/embed-posters/',$p1)"/>
Can anyone see a problem, it all looks good to me?
Are you using an XSLT 1 processor? The replace function appeared in XPath 2.0 and is therefore not available in XSLT 1.
In this case you could just use the translate function instead.
You have an extra unescaped less-than sign before your p variable's definition:
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
That's not valid syntax.
You should either remove it:
<xsl:variable name="p" select="replace($pre,'_','-')"/>
Or escape it:
<<xsl:variable name="p" select="replace($pre,'_','-')"/>
I see a '<<' at the start of line 4, is that it?