XSLT: Extract the latest DateTime of known predecessors within two xsl:for-each loops



Given is the following XML:



<?xml version="1.0" encoding="UTF-8"?>
<root>
<description>
<program version="2.2.0" type="plain">
<job id="MyJobID">
<step id="start_of_job">
<param name="begin_time">2014-09-29T16:54:44.920+0200</param>
<param name="end_time">2014-09-29T16:54:45.100+0200</param>
<param name="state">10</param>
</step>
<step id="step_1">
<param name="predlist">start_of_job</param>
<param name="begin_time">2014-09-29T16:54:49.454+0200</param>
<param name="end_time">2014-09-29T16:54:49.473+0200</param>
<param name="state">10</param>
</step>
<step id="step_2">
<param name="predlist">start_of_job</param>
<param name="begin_time">2014-09-29T16:54:48.643+0200</param>
<param name="end_time">2014-09-29T16:54:48.675+0200</param>
<param name="state">10</param>
</step>
<step id="step_3">
<param name="predlist">step_1</param>
<param name="rc">0</param>
<param name="begin_time">2014-09-29T16:54:49.442+0200</param>
<param name="end_time">2014-09-29T16:54:49.554+0200</param>
<param name="state">10</param>
</step>
<step id="step_4">
<param name="predlist">step_1 step_3</param>
<param name="begin_time">2014-09-29T16:54:54.258+0200</param>
<param name="end_time">2014-09-29T16:55:49.958+0200</param>
<param name="state">10</param>
</step>
<step id="step_5">
<param name="predlist">step_1 step_2 step_4</param>
<param name="begin_time">2014-09-29T16:55:54.550+0200</param>
<param name="end_time">2014-09-29T16:55:58.105+0200</param>
<param name="state">10</param>
</step>
<step id="end_of_job">
<param name="predlist">start_of_job step_1 step_2 step_3 step_4 step_5</param>
<param name="state">3</param>
</step>
</job>
</program>
</description>
<content />
</root>


The objective is to obtain the end_time of the known predecessor steps in predlist, to calculate the time between the actual step start_time and the predecessor step end_time which is the latest one of the given predecessors. E.g. for Step_5 this would be the end_time of Step_4 in this case. But this won't be like this every time & the number of steps is variable. The steps are processed parallel that is why sorting the nodes by end_time won't do it in this case. But maybe I'm wrong.


I'm not very experienced with XSLT. Here is what I figured out so far:



<xsl:stylesheet
xmlns:xsl="http://ift.tt/tCZ8VR"
xmlns:java="http://ift.tt/Y48VNG"
xmlns:xs="http://ift.tt/tphNwY"
xmlns:exsl="http://exslt.org/common"
version="2.0">

<!-- Add new element -->
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
<xsl:for-each select="root/description/program/job/step">
<xsl:if test="param[@name='state']=10">

<!-- Retrieve predecessor list -->
<xsl:variable name="predList" select="tokenize(param[@name='predlist'], ' ')"/>

<!-- Check which predecessor finished last -->
<xsl:for-each select="$predList">
<xsl:variable name="predecessor" select="."/>
<!-- Obtain end_time of predecessor and store it in a xsl:variable e.g. $received__predecessor_end_time somehow -->
</xsl:for-each>

<!-- Process ouput XML -->
<program>
<xsl:attribute name="stepID">
<xsl:value-of select="@id"/>
</xsl:attribute>

<xsl:attribute name="waitTime">
<!-- Calculate wait time in seconds -->
<xsl:call-template name="duration_in_s">
<xsl:with-param name="dateTimeBegin" select="substring(param[@name='begin_time'],1,23)"/>
<xsl:with-param name="dateTimeEnd" select="substring($received__predecessor_end_time,1,23)"/>
</xsl:call-template>
</xsl:attribute>
</program>
</xsl:if>
</xsl:for-each>
</xsl:template>

<!-- Template: Calculate wait time in seconds -->
<xsl:template name="duration_in_s">
<xsl:param name="dateTimeBegin"/>
<xsl:param name="dateTimeEnd"/>

<xsl:variable name="DURATION"><xsl:value-of select="xs:dateTime($dateTimeBegin)-xs:dateTime($dateTimeEnd)" /></xsl:variable>
<xsl:value-of select="((hours-from-duration($DURATION)*3600)+(minutes-from-duration($DURATION)*60)+seconds-from-duration($DURATION))" />
</xsl:template>
</xsl:stylesheet>


My problem is the scope within xsl:for-each $predList loop. Within this loop I cannot access any node to obtain its end_time. I guess my approach is wrong here.


How can I get the end_time value of the $predList predecessors & in addition to that figure out which of them is the latest one?


Note that this could be multiple DateTime values, which need to be compared with each other. XSLT 2.0 can be used here.


No comments:

Post a Comment