applying class to element found with test - class

I'm still new to working with XSLT
How do I apply a class to an element found with an xsl:if
XML:
<ColumnBody><h3>Some Text</h3></ColumnBody>
The output that I want:
<h3 class="box-list-link">Some Text </h3>
I have something that does this:
<xsl:for-each select ="./ColumnBody" >
<xsl:call-template name="RichText"></xsl:call-template>
</xsl:for-each>
<xsl:template name="RichText">
<p>
<xsl:copy-of select="./node()" />
</p>
</xsl:template>

Would something like this work for you?
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="h3">
<h3 class="box-list-link">
<xsl:apply-templates/>
</h3>
</xsl:template>
</xsl:stylesheet>

Related

XSLT group by and then copy child node by "n" number of times

I need to group the company and the maximum number the node row can occur in the new node group is 3.
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:decimal-format name="coerce" NaN="0"/>
<xsl:template match="/root">
<root>
<!--Group by fields, can only group by 1 element each time-->
<xsl:for-each-group select="row" group-by="Company">
<xsl:for-each-group select="current-group()" group-by="Department">
<xsl:for-each select="current-group()">
<!--Create a variable for the row count-->
<xsl:variable name="Grpcounter" select="number(position())"/>
<xsl:if test="$Grpcounter < 3">
<xsl:call-template name="Group">
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:for-each-group>
</root>
</xsl:template>
<xsl:template name="Group">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
could you pls update your xslt as follows:
replace: <xsl:template match="/root"> . . . </xsl:template> with
<xsl:template match="/root">
<xsl:variable name="grouped">
<!--Group by fields, can only group by 1 element each time-->
<xsl:for-each-group select="row" group-by="Company">
<!--<xsl:for-each-group select="current-group()" group-by="Department">-->
<xsl:for-each select="current-group()">
<xsl:choose>
<xsl:when test="position() mod 3 = 1">
<Group>
<xsl:call-template name="Group"/>
</Group>
</xsl:when>
<xsl:otherwise>
<Group1>
<xsl:call-template name="Group"/>
</Group1>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
<!--</xsl:for-each-group>-->
</xsl:for-each-group>
</xsl:variable>
<root>
<xsl:for-each-group select="$grouped/*" group-starting-with="Group">
<Group>
<xsl:copy-of select="current-group()/row"/>
</Group>
</xsl:for-each-group>
</root>
</xsl:template>
to get your expected output. See result

How to get the weekday from a date with XSLT? [duplicate]

Trying to calculate day of the week number from date. Found some examples in the internet, but instead of day of the week number i see this : NaN.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="date">
<xsl:copy>
<xsl:call-template name="date-format">
<xsl:with-param name="date-time" select="."/>
</xsl:call-template>
</xsl:copy>
</xsl:template>
<xsl:template name="date-format">
<xsl:param name="date-time"/>
<xsl:param name="date" select="substring-before($date-time,'T')"/>
<xsl:param name="year" select="substring-before($date,'-')"/>
<xsl:param name="month"
select="substring-before(substring-after($date,'-'),'-')"/>
<xsl:param name="day" select="substring-after(substring-after($date,'-'),'-')"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year - $a"/>
<xsl:variable name="m" select="$month + 12 * $a - 2"/>
<xsl:value-of select="($day + $y + floor($y div 4) - floor($y div 100)
+ floor($y div 400) + floor((31 * $m) div 12)) mod 7"/>
</xsl:template>
</xsl:stylesheet>
.
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test2.xsl" type="text/xsl" ?>
<document>
<date>2013-01-01</date>
<date>2013-05-24</date>
<date>2013-12-25</date>
<date>1957-07-13</date>
<date>1776-07-04</date>
</document>
The following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="date">
<xsl:call-template name="day-of-week">
<xsl:with-param name="date" select="."/>
</xsl:call-template>
</xsl:template>
<xsl:template name="day-of-week">
<xsl:param name="date"/>
<xsl:variable name="year" select="substring($date,1, 4)"/>
<xsl:variable name="month" select="substring($date, 6, 2)"/>
<xsl:variable name="day" select="substring($date, 9, 2)"/>
<xsl:variable name="a" select="floor((14 - $month) div 12)"/>
<xsl:variable name="y" select="$year + 4800 - $a"/>
<xsl:variable name="m" select="$month + 12*$a - 3"/>
<xsl:variable name="JDN" select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
<xsl:value-of select="($JDN + 1) mod 7" />
</xsl:template>
</xsl:stylesheet>
when applied to your input example:
<document>
<date>2013-01-01</date>
<date>2013-05-24</date>
<date>2013-12-25</date>
<date>1957-07-13</date>
<date>1776-07-04</date>
</document>
will return the following result:
<?xml version="1.0" encoding="UTF-8"?>
25364
Note:
The main problem with your attempt is this:
<xsl:param name="date" select="substring-before($date-time,'T')"/>
Your input has dates, not date-times, and they do not contain "T".

XSLT1.0 Add child element only once if does not exist

I am trying to add an element called Stamping one time and only if it doesn't exist in the message.
<!-- Copy all other elements -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
<xsl:template match="/*[local-name()='Envelope']/*[local-name()='Body']/*/*[not(*[local-name()='Stamping'])]">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
<v1:Stamping>
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
</v1:Stamping>
</xsl:template>
My problem occurs because the new v1:Stamping value is repeated for every child like this based on my existing match:
<envelope>
<body>
<operationName>
<child1 Catalog="1" />
<v1:Stamping>
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
<v1:Stamping>
<child2 Catalog="2" />
<v1:Stamping>
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
</v1:Stamping>
</operationName>
</body>
</envelope>
I need to see the result where stamping is only added one time as a child element of operationName. operationName is an element that will exist but this XSLT will be applied across many services and the value in operationName will be different depending on the service where this XSLT will be applied. This example below would be the needed output.
<envelope>
<body>
<operationName>
<child1 Catalog="1" />
<child2 Catalog="2" />
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
</operationName>
</body>
</envelope>
I need to see the result where stamping is only added one time as a
child element of operationName.
Then write a template especially for operationName elements:
<xsl:template match="operationName">
and check whether v1:Stamping already exists as one of its children:
<xsl:if test="not(v1:Stamping)">
If it does not exist already, it is added to the output tree.
Assuming the following XML, where there is no v1:Stamping element, as input:
XML Input
<?xml version="1.0" encoding="UTF-8"?>
<envelope>
<body>
<operationName>
<child1 Catalog="1"/>
<child2 Catalog="2"/>
</operationName>
</body>
</envelope>
Stylesheet
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:v1="http://www.v1.com" xmlns:v2="http://www.v2.com">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="operationName">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
<xsl:if test="not(v1:Stamping)">
<v1:Stamping>
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
</v1:Stamping>
</xsl:if>
</xsl:copy>
</xsl:template>
</xsl:transform>
XML Output
<?xml version="1.0" encoding="UTF-8"?>
<envelope>
<body>
<operationName>
<child1 Catalog="1"/>
<child2 Catalog="2"/>
<v1:Stamping xmlns:v1="http://www.v1.com" xmlns:v2="http://www.v2.com">
<v2:UserData CityCode="NO Stamping" Role="User" SecurityId="55"/>
</v1:Stamping>
</operationName>
</body>
</envelope>

How do we test whether a date is within 180 days from today in xslt in datapower

I am writing an xslt for datapower and in that I am getting a date(Payment Date).I have to check whether that date(Paymentt Date) is within 180 days of current date
I am getting present date by the following
<xsl:variable name="timestamp" select="date:date-time()"/>
Now how to check the condition for 180 days
Following is my xslt
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:date="http://exslt.org/dates-and-times"
xmlns:dpconfig="http://www.datapower.com/param/config"
extension-element-prefixes="dp"
exclude-result-prefixes="dp dpconfig"
>
<xsl:output method="xml"/>
<xsl:template match="/">
<PaymentDate><xsl:value-of select="dp:http-request-header('X-payment-date')"/></PaymentDate> (From request I am getting payment date)
<xsl:variable name="timestamp" select="date:date-time()"/> (From here I am getting present date)
<xsl:if (this is what I am confused)
Thanks
Calculating date difference in XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<output>
<difference>
<xsl:call-template name="date-difference">
<xsl:with-param name="date1" select="input/originalDate" />
<xsl:with-param name="date2" select="date:date-time()" />
</xsl:call-template>
</difference>
</output>
</xsl:template>
<xsl:template name="date-difference">
<xsl:param name="date1"/>
<xsl:param name="date2"/>
<xsl:param name="JDN1">
<xsl:call-template name="JDN">
<xsl:with-param name="date" select="$date1" />
</xsl:call-template>
</xsl:param>
<xsl:param name="JDN2">
<xsl:call-template name="JDN">
<xsl:with-param name="date" select="$date2" />
</xsl:call-template>
</xsl:param>
<xsl:value-of select="$JDN2 - $JDN1"/>
</xsl:template>
<xsl:template name="JDN">
<xsl:param name="date"/>
<xsl:param name="year" select="substring($date, 1, 4)"/>
<xsl:param name="month" select="substring($date, 6, 2)"/>
<xsl:param name="day" select="substring($date, 9, 2)"/>
<xsl:param name="a" select="floor((14 - $month) div 12)"/>
<xsl:param name="y" select="$year + 4800 - $a"/>
<xsl:param name="m" select="$month + 12*$a - 3"/>
<xsl:value-of select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" />
</xsl:template>
</xsl:stylesheet>
When applied to the following input XML:
<input>
<originalDate>2013-09-15</originalDate>
</input>
The result will be:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<difference>179</difference>
</output>
if the transformation is performed today, 2014-03-13.
IBM Datapower provides extension to existing EXSLT function. There is a function called 'difference' with following signature.
difference()
Returns the duration between the first date and the second date.
Syntax
date:difference(start-dateTime, end-dateTime)
You can utilize this function to find out the date-difference. For more information about extension function available in datapower see below link. Go to Chapter 5 and look for functions for manipulating 'date time'.
http://pic.dhe.ibm.com/infocenter/wsdatap/v3r8m1/topic/xm70/ExtensionFunctions.pdf
-Ajitabh
DataPower Supports Date:Difference
difference()
Returns the duration between the first date and the second date.
Syntax
date:difference(start-dateTime, end-dateTime)
You can pass current date as end-DateTime , date which wants to check as start-DateTime
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"
xmlns:date="http://exslt.org/dates-and-times" version="1.0">
<!--<xsl:key name="lang" match="element" use="#language"></xsl:key>-->
<xsl:template match="/">
<xsl:variable name="date1" select="date:date-time()"/>
<xsl:variable name="date2" select="'2013-09-15'"/>
<output>
<difference>
<xsl:value-of select="translate(date:difference($date2, $date1),'PD','')"/>
</difference>
</output>
</xsl:template>
</xsl:stylesheet>

Convert XML Option element nodes to HTML Option tags

Is there a direct was to convert an Element Object to an HTMLOption Object?
Let's suppose I have this XML:
<?xml version='1.0'?>
<options>
<option value="1">Hello1</option>
<option value="2">Hello2</option>
</options>
I want to insert each option in this select
Is there a way to just convert these XML to option directly or I have to then navigate the XML then get all information I need and then create a new Option and add that option to the select?
something like:
var options = XmlCode.getElementsByTagName('option');
for(var i = 0; i < options.length; i++){
selectBox.add(options[i]);
}
as a native code would be nice ^^
Note: I don't want to use any libraries or frameworks. I want do learn and do this by myself.
XSLT is made for XML to HTML conversion. Something like this will do the trick:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="select2option.xml" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml"
>
<xsl:output method="html" encoding="utf-8" indent="yes" standalone="yes" media-type="text/html" omit-xml-declaration="yes" doctype-system="about:legacy-compat" />
<html:options>
<html:option name="foo">bar</html:option>
</html:options>
<xsl:template match="xsl:stylesheet">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="html:options">
<select>
<xsl:apply-templates />
</select>
</xsl:template>
<xsl:template match="html:option">
<option name="#name">
<xsl:apply-templates />
</option>
</xsl:template>
</xsl:stylesheet>