Mapper: if/otherwise - biztalk

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.

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.

microsecond to readable datetime in xsl

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>

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>

XSLT Informal Time Translation

I'm currently working on a translation of documents for importing as XML to another system, and this involves the translation of a quite informal representation of time, such as the following:
<estimated-time>15 mins<estimated-time>
And I need to translate this to something like the following:
<tr:estimated_time>00:15:00</tr:estimated_time>
I've messed around with tokenizing, substrings, and the various time functions and haven't been able to come up with anything, though I am quite inexperienced in XSLT.
Following Jirka's answer, I tried the following:
<xsl:template match="estimated-time">
<tr:estimated_time>
<xsl:value-of select="time:parseTime(./text(), 'hours')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="time:parseTime(./text(), 'mins')"/>
<xsl:text>:</xsl:text>
<xsl:value-of select="time:parseTime(./text(), 'seconds')"/>
</tr:estimated_time>
</xsl:template>
<xsl:function name="time:parseTime">
<xsl:param name="testedString"/>
<xsl:param name="lookingFor"/>
<xsl:variable name="tokens" select="tokenize($testedString, ' ')" />
<xsl:variable name="out">
<xsl:choose>
<xsl:when test="$tokens[. = $lookingFor]">
<xsl:variable name="pos" select="index-of($tokens, $lookingFor)-1"/>
<xsl:value-of select="$tokens[$pos]"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>00</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="if (string-length($out)=1) then concat('0', $out) else $out"/>
</xsl:function>
Which always resulted in:
<tr:estimated_time>00:00:00</tr:estimated_time>
Any assistance would be greatly appreciated.
Update: it works! There were some weird newlines all over the original that I hadn't spotted, which were preventing it from working.
Might be there is a more sofisticated or cleaner solution but using tokenizing it should be done for example in this way
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:tst="test">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<times>
<xsl:apply-templates select="times/time" />
</times>
</xsl:template>
<xsl:template match="time">
<time>
<xsl:value-of select="tst:getSomething(.,'hours')" />
<xsl:text>:</xsl:text>
<xsl:value-of select="tst:getSomething(.,'mins')" />
<xsl:text>:</xsl:text>
<xsl:value-of select="tst:getSomething(.,'sec')" />
</time>
</xsl:template>
<xsl:function name="tst:getSomething">
<xsl:param name="testedString" />
<xsl:param name="lookingFor" />
<xsl:variable name="tokens" select="tokenize($testedString, ' ')" />
<xsl:variable name="tmp">
<xsl:choose>
<xsl:when test="$tokens[. = $lookingFor]">
<xsl:variable name="pos" select="index-of($tokens, $lookingFor) - 1" />
<xsl:value-of select="$tokens[$pos]" />
</xsl:when>
<xsl:otherwise>
<xsl:text>00</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="if (string-length($tmp) = 1) then concat('0', $tmp) else $tmp" />
</xsl:function>
</xsl:stylesheet>
It produces output
<?xml version="1.0" encoding="UTF-8"?>
<times>
<time>05:30:00</time>
<time>00:05:00</time>
</times>

Resources