I'm new to xsl and have a problem. I always get "NaN" when i try to do the following:
<xsl:variable name="amount" select="format-number(ARTICLE_PRICE/PRICE_LINE_AMOUNT, '0,00')" />
<xsl:variable name="quantity" select="format-number($quantity, '0,0#')"/>
<xsl:value-of select="format-number($amount * $quantity, '0,00')" />
Can someone tell me what i am doing wrong?
One possible reason out of several:
The result of format-number() is a string; if the string cannot be converted back to a number - for example, if it contains a comma - then you cannot multiply by it.
Well, if i do it like this:
<xsl:variable name="quantity" select="format-number($quantity, '0,0#')"/>
<xsl:value-of select="format-number(ARTICLE_PRICE/PRICE_LINE_AMOUNT * $quantity, '0,00')" />
It works. Still curious why it didn't work if i set the variable "amount"..
The 'NaN' value means you try to use format-number() on a value that is empty or not a valid number.
You have to test the value before using them as number, and formatting them before multiplying them is useless (if you don't use them elsewhere)
Related
I am outputting the name node of each property node in a ; delimited string as following:
<xsl:value-of select="properties/property/name" separator=";" />
I want to alter this such that each element is prefixed with _. An example output should be:
_alpha;_beta;_gamma
I tried the following:
<xsl:value-of select="concat('_', properties/property/name)" separator=";" />
I want to use this to create an output node containing that string:
<my_node>
<xsl:value-of select="concat('_', properties/property/name)" separator=";" />
</my_node>
This gives an error when there are multiple properties:
XPTY0004: A sequence of more than one item is not allowed
as the second argument of fn:concat() (<name>, <name>)
Is there a way to get this working in XSLT 2.0/3.0?
I could resort to the XSLT 1.0 for-each solution as given in https://stackoverflow.com/a/57856287/12042211 (in which we are manually adding the separator), but I am wondering if something elegant in XSLT 2.0/3.0 is possible.
The answer is yes. XSLT 2.0 allows you to write expressions like this...
<xsl:value-of select="properties/property/concat('_', name)" separator=";" />
So, for each property it selects the concatenation of "_" with the name element.
Such syntax is not valid in XSLT 1.0 though.
In XSLT 3.0 I would tend to write this as
<xsl:value-of select="properties/property ! ('_' || name)" separator=";" />
and perhaps use string-join() instead of xsl:value-of. You haven't shown the context, but try to use xsl:value-of only when you really want a text node, not when you just want a string.
The following is giving me the "memberstable is an unexpected token" error.
<xsl:when value-of memberstable/#member_cancontactthem =1>
<td bgcolor="#ff00ff">
<xsl:value-of select="You can contact this member"/></td>
</xsl:when>
I've used this to initialize it:
<xsl: value of select = "memberstable/#member_cancontactthem" />
The value in the DB is boolean, so either 1 or 0.
Until now, all suggestions will produce errors if I am not mistaken. xsl:when needs a test attribute:
<xsl:when test="memberstable[#member_cancontactthem='1']">
is the correct syntax. Also, xsl:when must be inside an xsl:choose element.
In general, please be careful with whitespace, and with hyphenations (for instance, value of is not the same as value-of) and make sure all attribute values are between quotes. XSLT must respect the rules of XML, which is not as forgiving as HTML.
I have the below xsl tag
<RectypeLegType>
<xsl:value-of select="../#id" />
</RectypeLegType>
and there can be two possible out come values of this as shown below..
1) <RectypeLegType>fixedLeg_612822</RectypeLegType>
2)<RectypeLegType>floatingLeg_194743</RectypeLegType>
but i want this value to be dispalyed as
<RectypeLegType>fixedLeg</RectypeLegType>
<RectypeLegType>floatingLeg</RectypeLegType>
now please advise how can i achieve this possible outcome i need to do cheanges in my please advise what changes need to be done
Assuming the underscore will always exist in the id attribute:
<RectypeLegType>
<xsl:value-of select="substring-before(../#id, '_')" />
</RectypeLegType>
<xsl:variable name="date1" select="2011-10-05"/>
<xsl:variable name="date2" select="2011-10-05"/>
<xsl:variable name="date3" select="2011-10-06"/>
<xsl:if test="$date2 = $date1 or $date2 < $date1">
..do something
</xsl:if>
<xsl:if test="$date3 = $date1 or $date3 > $date1">
.. do something
</xsl:if>
Both should evaluate true, but the second if doesn't. For the life of me I can't comprehended why!
In the actual transform the dates themselves are being drawn from an XML document but debugging through VS2010 i can see the values are as above.
Must be something fairly fundamental i'm doing wrong - any help would be brilliant!
I tried this in Oxygen/XML... select="2011-10-05 is being interpreted as an arithmetic expression, giving the value 1996 (2011 minus 10 minus 5) and "2011-10-06" is intrepreted as 1995.
What you want is
<xsl:variable name="date1" select="'2011-10-05'"/>
<xsl:variable name="date2" select="'2011-10-05'"/>
<xsl:variable name="date3" select="'2011-10-06'"/>
Note the extra single quotes.
From the XSLT 1.0 Specification:
If the variable-binding element has a select attribute, then the value
of the attribute must be an expression and the value of the variable
is the object that results from evaluating the expression.
I want to select an element by index with the indexed number being passed in with a param, the param is being passed in via PHP. Here's what I am trying:
//PHP
$xslt->setParameter('','player',$player);
$xslt->importStylesheet( $XSL );
print $xslt->transformToXML( $data );
//xslt
<xsl:param name="player" data-type="number"/>
<template match="/">
<xsl:value-of select="result[$player]/#name" />
</template>
And I know the value of the param is being passed correctly because I can just output the value of the param ($player) and it will output the correct value. If I hard code the indexed number "$player" to any number of index I want like below:
<template match="/">
<xsl:value-of select="result[2]/#name" />
</template>
it works. So, what I am doing wrong here. Can you not use params/variables to select indexes?
It may be evaluating the value of your xsl:param as a string, rather than a number. You can try explicitly converting it to a number using the number() function.
<xsl:value-of select="result[number($player)]/#name" />
The predicate filter specifying a number is short-hand for [position()=$param]. You can use xsl:param inside the predicate filter, like this, and it will evaluate the xsl:param value as a number:
<xsl:value-of select="result[position()=$player]/#name" />
If I hard code the indexed number
"$player" to any number of index I
want like below:
<template match="/">
<xsl:value-of select="result[2]/#name" />
</template>
it works.
No, any compliant XSLT processor will not select anything.
result[2]/#name
is a relative expression against the current node, and the current node is the / -- document-node.
Any well-formed XML document has exactly one top element (never two), therefore
result[2]
is equivalent to:
/result[2]
and doesn't select anything.
Most probably you are dealing with another expression, which you haven't shown (or the template is not matching just /).
Also:
<xsl:param name="player" data-type="number"/>
this is invalid syntax. The <xsl:param> instruction doesn't have a data-type attribute.
In fact, in XSLT 1.0 there isn't any way to specify the type of variables or parameters.
This is why in:
result[$player]/#name
$player is treated as string -- not as an integer.
To achieve the "indexing" you want, use:
result[position()=$player]/#name
The position() function returns a number and this causes the other operand of the = operator to be converted to (and used as) number.