Date compare in XSLT - xslt

I want to compare two dates in XSLT (1.0). Here I have mentioned hard coded dates
<xsl:variable name="DATE1" select="ms:format-date(16-FEB-19, 'dd-MMM-yy')" />
<xsl:variable name="DATE2" select="ms:format-date(01-MAY-19, 'dd-MMM-yy')" />
<xsl:if test="$DATE1 $lt; $DATE2">
</xsl:if>
I tried above but not getting proper result.

It looks like you're using some kind of extension function ms:format-date to format the dates. If you can format them as pure numeric YYYYMMDD then you can compare them as numbers. XSLT 1.0 does not offer a "<" operator for strings, let alone for dates.
Do think about moving forward to a later XSLT version (available from third parties) rather than asking the StackOverflow community to help you use a 20-year old version of the language.

Related

XSLT format-number with comma for indian price

I want to display a price for India, like this:
5,55,555
And not
555,555
There should be no decimal. There should be a comma, like this:
1,000 one thousand
10,000 ten thousand
1,00,000 one lakh
My code:
<Price>555555</Price>
<xsl:decimal-format name="Format_INR" grouping-separator="," />
<xsl:value-of select="format-number(Price, '#,##,###', 'Format_INR')" />
But it displays
555,555
What did I do wrong?
Thank you for your help.
The XSLT 2.0 specification of format-number() allows irregular grouping separators as in your example.
The XSLT 1.0 specification is based on the Java specification of DecimalFormat, which requires regular intervals between grouping separators.
(To be more precise: the JDK 7 spec requires regular intervals, or at any rate, it treats the last interval as the one to be used: (the interval between the last one and the end of the integer is the one that is used. So "#,##,###,####" == "######,####" == "##,####,####". But the XSLT 1.0 spec refers specifically to JDK 1.1.8, which is pretty-well unobtainable nowadays; my recollection is that it was very vague on such questions, and later versions of the JDK specification essentially documented the bugs in the initial implementation. To the extent that JDK 1.1.8 was vague, XSLT 1.0 implementations are free to do their own thing.)
As already mentioned, in XSLT 2.0 you can use:
<xsl:value-of select="format-number(Price, '#,##,###')" />
This will accommodate numbers up to 9,999,999. Above that, you need to add more separators, e.g.:
<xsl:value-of select="format-number(Price, '##,##,##,###')" />
will work for numbers up to 999,999,999 and so on.
In XSLT 1.0 you can do:
<xsl:choose>
<xsl:when test="Price >= 1000">
<xsl:value-of select="format-number(floor(Price div 1000), '#,##')" />
<xsl:text>,</xsl:text>
<xsl:value-of select="format-number(Price mod 1000, '000')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number(Price, '#,###')" />
</xsl:otherwise>
</xsl:choose>
This will work for any magnitude of Price. If you need to reuse this, consider making it a named template.
Note that neither method requires you to define a xsl:decimal-format.

displaying the result of xsl in cusomised format

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>

How to Get Correctly formatted date using Xslt?

I have a xslt code for getting the date from the database.the code is working correctly and I got the output ,but the problem is the date is not in correct format.here is the result.
output: 2013-05-07T11:27:46.7+02:00
my code is
<xsl:variable name="lastchange" select="shop:ExecStoredProcedure('kt_Lastchange',concat('#account:',$accid,',#itemnumber:',id))"></xsl:variable>
<textarea>
<xsl:value-of select ="$lastchange"/>
</textarea>
anyone can help for getting the correctly format of date?
If you are using
XSLT 1.0 version, use EXSLT - date:format-date date extension
XSLT 2.0 version, use built-in: Formatting Dates and Times date extension
Code
<xsl:variable name="dt" as="xs:dateTime" select="xs:dateTime('2012-10-21T22:10:15')"/>
<xsl:value-of select="format-dateTime($dt, '[Y0001]/[M01]/[D01]')"/>

Using dynamic xpath in XSLT

I am using a variable say xpathvar in the XSLT whose value will be supplied at the time of call to XSLT. How can i achieve this?
My XSLT file looks like -
<xsl:param name="xpathvar"/>
<xsl:param name="keyxpath"/>
<xsl:template match="/">
<listofResults>
<xsl:for-each select="$xpathvar">
<keyvalues><xsl:value-of select="xalan:evaluate(substring-before($keyxpath,'||'))"/></keyvalues>
<keyvalues><xsl:value-of select="xalan:evaluate(substring-after($keyxpath,'||'))"/></keyvalues>
</xsl:for-each>
</listofResults>
</xsl:template>
</xsl:stylesheet>
If I mention the variable in the for-each, it throws error. Please guide how can I achieve this.
Thanks!
According to Global xsl:param containing xpath expression string it can't be done purely with plain old XSLT, you need to use the evaluate extension see: Xalan evaluate expression
I dont think this can be done like this you must use xpath so example would be
<template match="Node[name=$xpathvar]" />
<xsl:for-each select="*[name()=$xpathvar]">
</xsl:for-each>
I think it does not let you use the variable directly because it is not a nodeset.
If I mention the variable in the
for-each, it throws error
In XSLT 1.0 (it looks you are using Xalan), you can iterate over node sets, only. So $xpathvar should be an instance of node set data type.
In XSLT 2.0 you can iterate over sequence (including scalar values).
Also, if the string containing the "dynamic" XPath expression is simple enough (only QName test step, maybe positional predicates) this could be done (as is already answered in SO) with standar XSLT.

XSL: Combining grouping and call-template

I've read with interest the techniques available on the web to extract a unique list of items from a XML file containing duplicates using XSL.
These range into 2 categories:
1) The Muenchian method (example: http://www.jenitennison.com/xslt/grouping/)
2) Or the previous-sibling look-up
These both rely on an XPath expression to select the data to group by.
However, in the XML file that I'm trying to work out, the data is not present "natively" in the XML file. I am using a xsl:template to compute some aggregated data from my elements. And I would like to group based on the aggregated data.
For example I have:
<filmsreview>
<record><data name='movie'>Star Wars</data><data name='ratings'>John:Good, Mary:Good</data></record>
<record><data name='movie'>Indiana Jones</data><data name='ratings'>John:Good, Mary:Bad, Helen:Average</data></record>
<record><data name='movie'>Titanic</data><data name='ratings'>John:Bad, Helen:Good</data></record>
</filmsreview>
I know that the structuration of data is not perfect and that by creating sub-elements I could do something easier, but I cannot change the data source easily, so let's take this as a challenge.
And I would like to build a recap where I have John's distinct ratings:
John's ratings:
Good
Bad
I have a xsl:template that can take a record element and return John's rating for this record:
Example:
<xsl:template name="get_rating">
<xsl:param name="reviewer" />
<!-- I use some string manipulation, and xsl:value-of to return the review for John-->
</xsl:template>
I can just call it under a xsl:for-each to get the exhaustive list of John's review. But I cannot combine this call with any of the methods to get unique values.
Do I have to use an intermediary XSL to convert my XML file to a more structured way? Or can I do in a single step?
Many thanks
Gerard
Hmm... This should be possible using xslt variables and the nodeset method, perhaps something like this:
<xsl:variable name="_johnsRatings">
<xsl:apply-templates select="/" mode="johnsRatings" />
</xsl:variable>
<xsl:variable name="johnsRatings" select="msxsl:node-set($_johnsRatings)" />
<xsl:template match="/" mode="johnsRatings">
<Ratings>
<xsl:for-each select="/filmsReview/record/data[#name='ratings']">
<Rating><xsl:call-template name="get_rating" /></Rating>
</xsl:for-each>
</Ratings>
</xsl:template>
At this point, it should be possible to query the $johnsRatings variable using standard XPath queries, and you can use either of the two methods you mentioned above to retrieve unique values from it...
Hope that helps
EDIT:
I don't know what XSLT engine you are using, I assumed you have access to the msxsl:node-set() function. However, most XSLT processors have similar methods, so you might have to search around for an equivalent method in your processor