XSL format-number acting weird - xslt

I have a weird problem with the XSL number formatting function. The function will
return NaN if i do not have two elements.
I am using the XSLT version 1.0 and the libxslt XSLT processor.
Exempli gratia
This will return not a number
<Weight><xsl:value-of select='format-number(weight, "#.00")'/></Weight>
However if i do it like this
<Weight><xsl:value-of select='format-number(weight, "#.00")'/></Weight>
<Weight><xsl:value-of select="weight"/></Weight>
i get the returned values.
What could be causing this behaviour?
Thanks in Advance!
EDIT
I found out that i could make PHP function calls in XSLT so i used
the PHP number_format function inorder to get the desired result.
<xsl:value-of select="php:functionString('number_format', weight, 2, '.', '')"/>
It solved my problem but it doesn't answer my question about why XSLT format-number
function is returning a NaN value.

Related

How to check for NaN in XSLT?

How do I check in XPath / XSLT whether a certain value is NaN?
One way of doing it is string($x) = 'NaN', but maybe there is a nicer / more efficient solution - something like JavaScript's isNaN function?
Solutions in XSLT 1 and XSLT 3 are welcome.

How to format number using format-number in xslt

I want to format float number in xslt? I know that I should use this function format-number, but don't really know.
example:
047.6000 to 47.60
You may use like this.
<xsl:value-of select="format-number(.,'#.00')"/>

Using the result of fn:floor() in a xsl:for-each range

I'm using XSLT 2.0 (Saxon) and am trying use the result of a floor() call as the upper bound to the range in a <xsl:for-each> loop.
<xsl:for-each select="1 to floor(string-length($input_string) div 2)">...</xsl:for-each>
I'm getting the error message:
XPTY0004: Required item type of second operand of 'to' is xs:integer;
supplied value has item type xs:decimal
I'd have thought that the resulting type of floor() would be an integer, but this seems to imply that floor will return a decimal if supplied a decimal: http://saxon.sourceforge.net/saxon7.8/functions.html#fn:floor
How do I get an integer so I can use it in my range?
You should be able to use select="1 to xs:integer(floor(string-length($input_string) div 2))", of course your stylesheet then needs to declare xmlns:xs="http://www.w3.org/2001/XMLSchema".
If continue to have problems the please tell us which Saxon version you use, the first to support XSLT 2.0 as specified in 2007 was Saxon 8.9, the current version is 9.5.
You could also use
select="1 to ($input_string idiv 2)"
though I would need to check the spec to be confident that this returns the same answer in all circumstances.

need to display char in xslt

Hi all
I am using xslt 1.0. I have the char code as FOA7 which has to displayed as a corresponding character. My input is
<w:sym w:font="Wingdings" w:char="F0A7"/>
my xslt template is
<xsl:template match="w:sym">
<xsl:variable name="char" select="#w:char"/>
<span font-family="{#w:fonts}">
<xsl:value-of select="concat('&#x',$char,';')"/>
</span>
</xsl:template>
It showing the error as ERROR: 'A decimal representation must immediately follow the "&#" in a character reference.'
Please help me in fixing this..Thanks in advance...
This isn't possible in (reasonable) XSLT. You can work around it.
Your solution with concat is invalid: XSLT is not just a fancy string-concatenator, it really transforms the conceptual tree. An encoded character such as  is a single character - if you were to somehow include the letters & # x f 0 a 7 ; then the XSLT processor would be required to include these letters in the XML data - not the string! So that means it will escape them.
There's no feature in XSLT 1.0 that permits converting from a number to a character with that codepoint.
In XSLT 2.0, as Michael Kay points out, you can use codepoints-to-string() to achieve this.
There are two solutions. Firstly, you could use disable-output-escaping. This is rather nasty and not portable. Avoid this at all costs if you can - but it will probably work in your transformer, and it's probably the only general, simple solution, so you may not be able to avoid this.
The second solution would be to hardcode matches for each individual character. That's a mess generally, but quite possible if you're dealing with a limited set of possibilities - that depends on your specific problem.
Finally, I'd recommend not solving this problem in XSLT - this is typically something you can do in pre/post processing in another programming environment more appropriately. Most likely, you've an in-memory representation of the XML document to be able to use XSLT in the first place, in which case this won't even take much CPU time.
<span font-family="{#w:font}">
<xsl:value-of select="concat('&#x', #w:char, ';')"
disable-output-escaping="yes"/>
</span>
Though check #Eamon Nerbonne's answer, why you shouldn't do it at all.
If you were using XSLT 2.0 (which you aren't), you could write a function to convert hex to decimal, and then use codepoints-to-string() on the result.
use '&' for '&' in output:
<xsl:value-of select="concat('&#x',$char,';')"/>

Including a plain text file with XSLT 1.0

How can I include the content of a plain text file in a result document from within an XSLT 1.0 stylesheet? I.e., just like document(), but without parsing it:
<xsl:value-of select="magic-method-to-include-plaintext(#xlink_href)" />
I am almost sure, that this doesn't work without extension, because:
there is a special XPath function defined for this in XSLT/XPath 2.0:
<xsl:value-of select="unparsed-text(#xlink:href, 'UTF-8')"/>
the XSLT FAQ only lists a Java extension to achieve this via EXSLT
However, perhaps I missed something?
However, perhaps I missed something?
No, XSLT 1.0 cannot access the content of a non-xml text file without using an extension function.
One way around this is to pass the string as a global parameter to the transformation.