microsecond to readable datetime in xsl - datetime

I want to transform the Date and Time in an xml file which is in "microsecond" to a human readable format like (2016-10-14) using XSLT 1.0 stylesheet transformation, this is the xml content below:
<?xml version="1.0" encoding="UTF-8"?>
<News DateTime="636120534151823750" Id="5241">
</News>
Many thanks,

Try it this way:
<xsl:template match="News">
<dateTime>
<xsl:call-template name="datetime.ticks-to-datetime">
<xsl:with-param name="datetime.ticks" select="#DateTime" />
</xsl:call-template>
</dateTime>
</xsl:template>
<xsl:template name="datetime.ticks-to-datetime">
<xsl:param name="datetime.ticks"/>
<xsl:variable name="JDN" select="floor($datetime.ticks div 864000000000) + 1721426" />
<xsl:variable name="rem-ticks" select="$datetime.ticks mod 864000000000"/>
<xsl:variable name="f" select="$JDN + 1401 + floor((floor((4 * $JDN + 274277) div 146097) * 3) div 4) - 38"/>
<xsl:variable name="e" select="4*$f + 3"/>
<xsl:variable name="g" select="floor(($e mod 1461) div 4)"/>
<xsl:variable name="h" select="5*$g + 2"/>
<xsl:variable name="d" select="floor(($h mod 153) div 5 ) + 1"/>
<xsl:variable name="m" select="(floor($h div 153) + 2) mod 12 + 1"/>
<xsl:variable name="y" select="floor($e div 1461) - 4716 + floor((14 - $m) div 12)"/>
<xsl:variable name="H" select="floor($rem-ticks div 36000000000)"/>
<xsl:variable name="M" select="floor($rem-ticks mod 36000000000 div 600000000)"/>
<xsl:variable name="S" select="$rem-ticks mod 600000000 div 10000000"/>
<xsl:value-of select="format-number($y, '0000')" />
<xsl:value-of select="format-number($m, '-00')"/>
<xsl:value-of select="format-number($d, '-00')"/>
<xsl:value-of select="format-number($H, ' 00')" />
<xsl:value-of select="format-number($M, ':00')"/>
<xsl:value-of select="format-number($S, ':00')"/>
</xsl:template>
Applied to your input example, the result will be:
<dateTime>2016-10-14 14:50:15</dateTime>

Related

Convert LDAP Timestamp to MM/dd/yyyy HH:mm:ss in XSLT 1.0

I am trying to convert a LDAP timestamp in XSLT 1.0 to a readable format (MM/dd/yyyy HH:mm:ss) but no matter what timestamp I input the date and time is always wrong. Anyone know where my issue is or if there is a better method? Thank you!
Here is my template.
<!-- Get last logon date from Active Directory -->
<xsl:call-template name="ticks-to-datetime">
<xsl:with-param name="commonName" select="'Last-Logon-to-Domain'" />
<xsl:with-param name="value" select="132278345110000000" />
</xsl:call-template>
<xsl:template name="ticks-to-datetime">
<xsl:param name="commonName"/>
<xsl:param name="value"/>
<xsl:variable name="JDN" select="floor($value div 864000000000) + 1721426" />
<xsl:variable name="rem-ticks" select="$value mod 864000000000"/>
<xsl:variable name="f" select="$JDN + 1401 + floor((floor((4 * $JDN + 274277) div 146097) * 3) div 4) - 38"/>
<xsl:variable name="e" select="4*$f + 3"/>
<xsl:variable name="g" select="floor(($e mod 1461) div 4)"/>
<xsl:variable name="h" select="5*$g + 2"/>
<xsl:variable name="d" select="floor(($h mod 153) div 5 ) + 1"/>
<xsl:variable name="m" select="(floor($h div 153) + 2) mod 12 + 1"/>
<xsl:variable name="y" select="floor($e div 1461) - 4716 + floor((14 - $m) div 12)"/>
<xsl:variable name="H" select="floor($rem-ticks div 36000000000)"/>
<xsl:variable name="M" select="floor($rem-ticks mod 36000000000 div 600000000)"/>
<xsl:variable name="S" select="$rem-ticks mod 600000000 div 10000000"/>
<xsl:element name="field">
<xsl:attribute name="commonName">
<xsl:value-of select="$commonName" />
</xsl:attribute>
<xsl:value-of select="format-number($m, '00/')"/>
<xsl:value-of select="format-number($d, '00/')"/>
<xsl:value-of select="format-number($y, '0000')"/>
<xsl:value-of select="format-number($H, ' 00')" />
<xsl:value-of select="format-number($M, ':00')"/>
<xsl:value-of select="format-number($S, ':00')"/>
</xsl:element>
</xsl:template>
Assuming that your input represents the number of 100-nanosecond units elapsed since 1601-01-01T00:00:00, you need to change:
<xsl:variable name="JDN" select="floor($value div 864000000000) + 1721426" />
to:
<xsl:variable name="JDN" select="floor($value div 864000000000) + 2305814" />
Then your template will return the result of 03/04/2020 22:28:31 for the input of 132278345110000000.

Xslt 1.0 : add months(integer) to date time format

I am new to xslt. I have two inputs in an xml as
input 1 is startDate in datetime format—2012-12-26T00:00:00
Input 2 is warrantyMonths in integer format —12 months
I want the output as endDate in dateTime format which will be startDate+warrantyMonths.
Request:
<ass:FinancialInfo xmlns:ass="******">
<ass:name>Test</ass:name>
<ass:warrantyMonths>12</ass:warrantyMonths>
<ass:startDate>2012-12-26T00:00:00</ass:startDate>
</ass:FinancialInfo>
How can i do this in xslt 1.0.
Thanks in advance
This is not easy to do in XSLT 1.0. Try it this way:
<xsl:template name="add-months-to-dateTime">
<xsl:param name="dateTime"/>
<xsl:param name="months-to-add"/>
<!-- extract components -->
<xsl:variable name="year" select="substring($dateTime, 1, 4)"/>
<xsl:variable name="month" select="substring($dateTime, 6, 2)"/>
<xsl:variable name="day" select="substring($dateTime, 9, 2)"/>
<xsl:variable name="time" select="substring-after($dateTime, 'T')"/>
<!-- calculate target year and month (using Knuth's corrected mod) -->
<xsl:variable name="m11" select="$month + $months-to-add - 1"/>
<xsl:variable name="y" select="$year + floor($m11 div 12)"/>
<xsl:variable name="m" select="$m11 - 12 * floor($m11 div 12) + 1"/>
<!-- calculate target day (clipped to last day of target month, excess days do not overflow) -->
<xsl:variable name="cal" select="'312831303130313130313031'"/>
<xsl:variable name="leap" select="not($y mod 4) and $y mod 100 or not($y mod 400)"/>
<xsl:variable name="month-length" select="substring($cal, 2 * ($m - 1) + 1, 2) + ($m = 2 and $leap)" />
<xsl:variable name="d">
<xsl:choose>
<xsl:when test="$day > $month-length">
<xsl:value-of select="$month-length"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$day"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- output -->
<xsl:value-of select="$y"/>
<xsl:value-of select="format-number($m, '-00')"/>
<xsl:value-of select="format-number($d, '-00')"/>
<xsl:text>T</xsl:text>
<xsl:value-of select="$time"/>
</xsl:template>
Example of call:
<xsl:template match="ass:FinancialInfo">
<xsl:copy>
<xsl:copy-of select="*"/>
<ass:endDate>
<xsl:call-template name="add-months-to-dateTime">
<xsl:with-param name="dateTime" select="ass:startDate"/>
<xsl:with-param name="months-to-add" select="ass:warrantyMonths"/>
</xsl:call-template>
</ass:endDate>
</xsl:copy>
</xsl:template>
If you can't upgrade to XSLT 2.0, consider whether you can use an implementation of the EXSLT dates-and-times module, see http://exslt.org/date/. You can download an implementation of this library at http://exslt.org/date/functions/add/date.add.template.xsl, and either just include it in your project, or extract the bits you need. The template named date:add should do what you need.

Recursive loop in Xslt 1.0

I am working on a recursive loop. Below is the sample code.
The loop gets executed only once. It is not executing until it reaches the maximum count (20 times).
Can you please help if this is an issue?
Thanks,
Raj
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xdoxslt='http://www.oracle.com/XSL/Transform/java/oracle.apps.xdo.template.rtf.XSLTFunctions'>
<xsl:output method="text" omit-xml-declaration="yes" />
<xsl:variable name="nl">
<xsl:value-of select="'
'"/>
<xsl:text xml:space="preserve">
</xsl:text>
</xsl:variable>
<xsl:template match = "ARCHIVE_CHEQUE_WRITER">
<xsl:for-each select="CHEQUE">
<xsl:variable name="ded" select="./AC_DEDUCTIONS"/>
<xsl:variable name="dedcount" select="count($ded)"/>
<xsl:variable name="earn" select="./AC_EARNINGS"/>
<xsl:variable name="earncount" select="count($earn)"/>
<xsl:value-of select="$dedcount"/>
<xsl:value-of select="$nl"/>
<xsl:value-of select="$earncount"/>
<xsl:value-of select="$nl"/>
<xsl:text>Starting New Record*******</xsl:text>
<xsl:value-of select="$nl"/>
<xsl:for-each select="./AC_DEDUCTIONS">
<xsl:text>This is sample template</xsl:text>
<xsl:value-of select="$nl"/>
</xsl:for-each>
<xsl:value-of select="$nl"/>
<xsl:value-of select="$nl"/>
<xsl:call-template name="recursive-loop">
<xsl:with-param name="pCount" select="20"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="recursive-loop">
<xsl:param name="pStart" select="1"/>
<xsl:param name="pCount"/>
<xsl:text> value of parameters</xsl:text>
<xsl:value-of select="$nl"/>
<xsl:value-of select="$pStart"/>
<xsl:value-of select="$pCount"/>
<xsl:value-of select="$nl"/>
<xsl:if test="$pCount > pStart">
<xsl:call-template name="recursive-loop">
<xsl:with-param name="pStart" select="$pStart+1"/>
<xsl:with-param name="pCount" select="$pCount"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
You forgot to use $ for variable pStart in the template
<xsl:if test="$pCount > $pStart">
<xsl:call-template name="recursive-loop">
<xsl:with-param name="pStart" select="$pStart+1"/>
<xsl:with-param name="pCount" select="$pCount"/>
</xsl:call-template>
</xsl:if>

Display Images from media directory using media picker not working

I am using Umbraco v6.1.6 and what I want is simply display the images from the media directory I select using media picker.
The content of media directory is as below:
And I have created an XSLT file named ImageSlider.xslt and the content of that file are as below:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umb="urn:umbraco.library"
exclude-result-prefixes="umb"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<xsl:template match="/">
<xsl:variable name="media" select="umb:GetMedia(1088, 0)" />
<xsl:if test="$media">
<img src="{$media/umbracoFile}" alt="{$media/altText}" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
here 1088 is the ID of the banner directory but it is not working at all. I am new to this.
Can anyone please help me ?
I'm assuming you want to select the folder and list all images underneath it. At the moment, your code is just trying to display the folder. You need something like this...
In my example, I'm using a multi-node tree picker and you can select images and folders, rendering out a csv. It will loop through it all and list out all the images
<xsl:for-each select="$source/value">
<xsl:variable name="imageId" select="number(current())" />
<xsl:if test="$imageId > 0">
<xsl:variable name="media" select="umbraco.library:GetMedia($imageId, 0)" />
<xsl:choose>
<xsl:when test="local-name($media) = 'Image'">
<xsl:call-template name="ImageBox">
<xsl:with-param name="imageId" select="$imageId"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="local-name($media) = 'Folder'">
<xsl:call-template name="LoopFolders">
<xsl:with-param name="folderId" select="$imageId"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="LoopFolders">
<xsl:param name="folderId"/>
<xsl:variable name="media" select="umbraco.library:GetMedia($folderId, 0)" />
<xsl:variable name="alt" select="$media/#nodeName" />
<div id="gallery">
<xsl:for-each select="umbraco.library:GetMedia($folderId, true())/Image">
<xsl:call-template name="ImageBox">
<xsl:with-param name="imageId" select="number(#id)"/>
</xsl:call-template>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template name="ImageBox">
<xsl:param name="imageId"/>
<xsl:if test="$imageId > 0">
<xsl:variable name="media" select="umbraco.library:GetMedia($imageId, 0)" />
<xsl:if test="$media">
<xsl:variable name="url" select="$media/umbracoFile" />
<xsl:variable name="width" select="$media/umbracoWidth" />
<xsl:variable name="height" select="$media/umbracoHeight" />
<xsl:variable name="alt" select="$media/#nodeName" />
<img src="{$url}" alt="{$alt}" width="{$width}" height="{$height}" />
</xsl:if>
</xsl:if>
</xsl:template>

Mapper: if/otherwise

why the mapper doesn't want to make the otherwise-query in the xslt-Dokument?
it should be:
if the script-functoid returns "true" --> it should copy the value from "PV1_19"-Segment in the "MRG_5"-Segment.
otherweise it should copied the MRG1-Segment from the left side to the right side --> i.e. if the MRG_1-Sement from the left side exists, then copy it; if not, it shouldn't exists a MRG-Segment in the Message.
This image shows how i maked it:
And this is the xslt-Code from the mapper:
- <xsl:for-each select="ZBE_BewegungsdatenSegment">
<xsl:variable name="var:v6" select="userCSharp:ChangeEventToA42(string(ZBE_5_SAPEVENT/text()) , string(ZBE_6_FAL_CASEPATNO/text()) , string(../MSH_MessageHeaderSegment/MSH.9_MessageType/CM_MSG.1_TriggerEvent/text()))" />
<xsl:variable name="var:v7" select="userCSharp:StringConcat("A42")" />
<xsl:variable name="var:v8" select="userCSharp:LogicalEq(string($var:v6) , string($var:v7))" />
- <xsl:if test="$var:v8">
<xsl:variable name="var:v9" select="string(ZBE_5_SAPEVENT/text())" />
<xsl:variable name="var:v10" select="string(ZBE_6_FAL_CASEPATNO/text())" />
<xsl:variable name="var:v11" select="string(../MSH_MessageHeaderSegment/MSH.9_MessageType/CM_MSG.1_TriggerEvent/text())" />
- <MRG_MergePatientInformation>
- <MRG_1_PriorPatientIdentifierList>
<xsl:variable name="var:v12" select="userCSharp:ChangeEventToA42($var:v9 , $var:v10 , $var:v11)" />
<xsl:variable name="var:v13" select="userCSharp:LogicalNe(string($var:v7) , string($var:v12))" />
- <xsl:if test="string($var:v13)='true'">
<xsl:variable name="var:v14" select="../MRG_MergePatientInformation/MRG_1_PriorPatientIdentifierList/CX_0_Id/text()" />
- <CX_0_Id>
<xsl:value-of select="$var:v14" />
</CX_0_Id>
</xsl:if>
<xsl:variable name="var:v15" select="userCSharp:LogicalEq(string($var:v12) , string($var:v7))" />
- <xsl:if test="string($var:v15)='true'">
<xsl:variable name="var:v16" select="""" />
- <CX_0_Id>
<xsl:value-of select="$var:v16" />
</CX_0_Id>
</xsl:if>
</MRG_1_PriorPatientIdentifierList>
- <MRG_2_PriorAlternatePatientId>
<xsl:variable name="var:v17" select="userCSharp:ChangeEventToA42($var:v9 , $var:v10 , $var:v11)" />
<xsl:variable name="var:v18" select="userCSharp:LogicalEq(string($var:v17) , string($var:v7))" />
- <xsl:if test="string($var:v18)='true'">
<xsl:variable name="var:v19" select="""" />
- <CX_0_Id>
<xsl:value-of select="$var:v19" />
</CX_0_Id>
</xsl:if>
</MRG_2_PriorAlternatePatientId>
- <MRG_3_PriorPatientAccountNumber>
<xsl:variable name="var:v20" select="userCSharp:ChangeEventToA42($var:v9 , $var:v10 , $var:v11)" />
<xsl:variable name="var:v21" select="userCSharp:LogicalEq(string($var:v20) , string($var:v7))" />
- <xsl:if test="string($var:v21)='true'">
<xsl:variable name="var:v22" select="""" />
- <CX_0_Id>
<xsl:value-of select="$var:v22" />
</CX_0_Id>
</xsl:if>
</MRG_3_PriorPatientAccountNumber>
- <MRG_4_PriorPatientId>
<xsl:variable name="var:v23" select="userCSharp:ChangeEventToA42($var:v9 , $var:v10 , $var:v11)" />
<xsl:variable name="var:v24" select="userCSharp:LogicalEq(string($var:v23) , string($var:v7))" />
- <xsl:if test="string($var:v24)='true'">
<xsl:variable name="var:v25" select="""" />
- <CX_0_Id>
<xsl:value-of select="$var:v25" />
</CX_0_Id>
</xsl:if>
</MRG_4_PriorPatientId>
- <MRG_5_PriorVisitNumber>
<xsl:variable name="var:v26" select="userCSharp:ChangeEventToA42($var:v9 , $var:v10 , $var:v11)" />
<xsl:variable name="var:v27" select="userCSharp:LogicalEq(string($var:v26) , string($var:v7))" />
- <xsl:if test="string($var:v27)='true'">
<xsl:variable name="var:v28" select="../PV1_PatientVisitSegment/PV1_19_VisitNumber/CX_0_Id/text()" />
- <CX_0_Id>
<xsl:value-of select="$var:v28" />
</CX_0_Id>
</xsl:if>
</MRG_5_PriorVisitNumber>
</MRG_MergePatientInformation>
</xsl:if>
</xsl:for-each>
do you know why the Mapper dosn't make a "otherwise-query" ( if (yes) and if( not(yes) ) )?
I've found the visual mapper does not work well for complicated mappings.
I switch to an external xslt mapping for anything very complicated.

Resources