|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:file="http://expath.org/ns/file"
|
|
xmlns:int="http://www.infrabel.be/INT"
|
|
xmlns:cern="http://www.infrabel.be/ups/timetable/2014/09"
|
|
xmlns:shared="urn:shared-functions"
|
|
xmlns:local="urn:local-functions"
|
|
version="2.0">
|
|
<xsl:import href="/shared/shared-functions.xslt"/>
|
|
<xsl:param name="output-folder" as="xs:string"/>
|
|
<xsl:param name="run-file" as="xs:string"/>
|
|
<xsl:param name="node-xml" as="document-node()"/>
|
|
<xsl:param name="routeEdge-xml" as="document-node()"/>
|
|
<xsl:param name="end-digit" as="xs:integer"/>
|
|
<xsl:strip-space elements="*"/>
|
|
<xsl:variable name="runXML" select="shared:open-file($run-file)"/>
|
|
<xsl:variable name="run" select="$runXML/run"/>
|
|
<xsl:variable name="timetable-folder" select="concat($run/@last-publish-folder, 'tms/train/')"/>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template match="trains">
|
|
<xsl:apply-templates select="train[@lastUpdateDate = current()/@creationDate][ends-with(@trainNo, string($end-digit))]"/>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template match="train">
|
|
<xsl:if test="position() = (1, last()) or position() mod 1000 = 0">
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Processing train ', position(), '/', last()))"/>
|
|
</xsl:if>
|
|
<!-- <xsl:if test="@trainNo = (10, 3655, 3668, 3690, 3691)">-->
|
|
<xsl:variable name="trainXML" select="shared:open-file($timetable-folder, @href)"/>
|
|
<xsl:variable name="train-1" select="local:get-microTrainVariant($trainXML, $run/@selectionLayer, $run/@creationDate, $run/@purgeDate)"/>
|
|
<xsl:variable name="train-2" select="local:add-traction-and-routeEdgeSections($train-1)"/>
|
|
<xsl:variable name="train-3" select="local:group-by-midnight($train-2)"/>
|
|
<xsl:variable name="train-4" select="local:filter-timetablePoints($train-3)"/>
|
|
<xsl:variable name="train" select="local:sort-microTrainVariant($train-4)"/>
|
|
<xsl:result-document href="{shared:path-to-uri($output-folder, @href)}" method="xml">
|
|
<xsl:sequence select="$train"/>
|
|
</xsl:result-document>
|
|
<!-- </xsl:if>-->
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-node-and-midnight" match="*">
|
|
<xsl:element name="{local-name()}">
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:apply-templates mode="add-node-and-midnight"/>
|
|
</xsl:element>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-node-and-midnight" match="cern:point">
|
|
<xsl:param name="departureDate" as="xs:string" tunnel="yes"/>
|
|
<xsl:variable name="node" select="local:get-node-for-id(@nodeId, $departureDate)"/>
|
|
<xsl:element name="{local-name()}">
|
|
<xsl:sequence select="@nodeSequenceNo, @nodeId"/>
|
|
<xsl:for-each select="$node">
|
|
<xsl:attribute name="nodeName" select="@name"/>
|
|
<xsl:attribute name="nodeClass" select="local-name()"/>
|
|
<xsl:attribute name="serZoneSymbolicName" select="@serZoneSymbolicName"/>
|
|
<xsl:sequence select="@serZoneSymbolicName, @ptrefId"/>
|
|
</xsl:for-each>
|
|
<xsl:sequence select="@* except (@nodeSequenceNo, @nodeId)"/>
|
|
<xsl:apply-templates mode="add-node-and-midnight"/>
|
|
</xsl:element>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-node-and-midnight" match="cern:in">
|
|
<xsl:element name="{local-name()}">
|
|
<xsl:choose>
|
|
<xsl:when test="exists(@time) and @time ne '00:00:00'">
|
|
<xsl:attribute name="midnight" select="(@midnight, 0)[1]"/>
|
|
<xsl:attribute name="time" select="@time"/>
|
|
</xsl:when>
|
|
<xsl:when test="exists(@time) and @time eq '00:00:00'">
|
|
<xsl:attribute name="midnight" select="(@midnight, 0)[1] - 1"/>
|
|
<xsl:attribute name="time" select="'24:00:00'"/>
|
|
</xsl:when>
|
|
</xsl:choose>
|
|
<xsl:sequence select="@* except (@midnight, @time)"/>
|
|
<xsl:apply-templates mode="add-node-and-midnight"/>
|
|
</xsl:element>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-node-and-midnight" match="cern:out">
|
|
<xsl:element name="{local-name()}">
|
|
<xsl:if test="exists(@time)">
|
|
<xsl:attribute name="midnight" select="(@midnight, 0)[1]"/>
|
|
<xsl:attribute name="time" select="@time"/>
|
|
</xsl:if>
|
|
<xsl:sequence select="@* except (@midnight, @time)"/>
|
|
<xsl:apply-templates mode="add-node-and-midnight"/>
|
|
</xsl:element>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-node-and-midnight" match="cern:infos"/>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-routeEdges add-traction-and-routeEdgeSections filter-timetablePoints group-by-midnight" match="*">
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:apply-templates mode="#current"/>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-routeEdges" match="point">
|
|
<xsl:variable name="routeEdgeNodes" select="local:get-routeEdgeNodes-for-point(.)"/>
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:apply-templates mode="add-routeEdges">
|
|
<xsl:with-param name="routeEdgeNodes" select="$routeEdgeNodes" tunnel="yes"/>
|
|
</xsl:apply-templates>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-routeEdges" match="in">
|
|
<xsl:param name="routeEdgeNodes" as="element()*" tunnel="yes"/>
|
|
<xsl:variable name="routeEdgeNode" select="$routeEdgeNodes[int:in/@port = current()/@port]"/>
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:apply-templates mode="add-routeEdges"/>
|
|
<xsl:for-each select="$routeEdgeNode">
|
|
<xsl:variable name="distance" select="@distance"/>
|
|
<xsl:for-each select="ancestor::int:routeEdge">
|
|
<xsl:element name="routeEdgeRef">
|
|
<xsl:attribute name="routeEdgeId" select="@id"/>
|
|
<xsl:attribute name="distance" select="$distance"/>
|
|
<xsl:attribute name="length" select="int:nodes/*[last()]/@distance"/>
|
|
<xsl:sequence select="@course"/>
|
|
</xsl:element>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-routeEdges" match="out">
|
|
<xsl:param name="routeEdgeNodes" as="element()*" tunnel="yes"/>
|
|
<xsl:variable name="routeEdgeNode" select="$routeEdgeNodes[int:out/@port = current()/@port]"/>
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:apply-templates mode="add-routeEdges"/>
|
|
<xsl:for-each select="$routeEdgeNode">
|
|
<xsl:variable name="distance" select="@distance"/>
|
|
<xsl:for-each select="ancestor::int:routeEdge">
|
|
<xsl:element name="routeEdgeRef">
|
|
<xsl:attribute name="routeEdgeId" select="@id"/>
|
|
<xsl:attribute name="distance" select="$distance"/>
|
|
<xsl:attribute name="length" select="int:nodes/*[last()]/@distance"/>
|
|
<xsl:sequence select="@course"/>
|
|
</xsl:element>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="add-traction-and-routeEdgeSections" match="microTrainVariant">
|
|
<xsl:variable name="timetablePoints-1" as="element()">
|
|
<xsl:apply-templates mode="add-routeEdges" select="timetablePoints"/>
|
|
</xsl:variable>
|
|
<xsl:variable name="tractionSections" select="local:create-tractionSections-from-timetable($timetablePoints-1)"/>
|
|
<xsl:variable name="routeEdgeSections" select="local:create-routeEdgeSections-from-timetable($timetablePoints-1)"/>
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*, *"/>
|
|
<xsl:element name="tractionSections">
|
|
<xsl:sequence select="$tractionSections"/>
|
|
</xsl:element>
|
|
<xsl:element name="routeEdgeSections">
|
|
<xsl:sequence select="$routeEdgeSections"/>
|
|
</xsl:element>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="filter-timetablePoints" match="midnightSection">
|
|
<xsl:variable name="filtered-points" as="element()*">
|
|
<xsl:apply-templates mode="filter-timetablePoints" select="routeEdgeSections/routeEdgeSection"/>
|
|
</xsl:variable>
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*, date"/>
|
|
<xsl:if test="exists($filtered-points)">
|
|
<xsl:element name="timetablePoints">
|
|
<xsl:sequence select="$filtered-points"/>
|
|
</xsl:element>
|
|
</xsl:if>
|
|
<xsl:sequence select="* except (date, timetablePoints)"/>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="filter-timetablePoints" match="routeEdgeSection" as="element(point)*">
|
|
<xsl:if test="empty(@routeEdgeId)">
|
|
<xsl:sequence select="ancestor::midnightSection/timetablePoints/point[(@nodeSequenceNo - current()/@outNodeSequenceNo ge 0) and (current()/@inNodeSequenceNo - @nodeSequenceNo ge 0)]"/>
|
|
</xsl:if>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="group-by-midnight" match="timetablePoints">
|
|
<xsl:variable name="timetablePoints" select="."/>
|
|
<xsl:variable name="microTrainVariant" select="ancestor::microTrainVariant"/>
|
|
<xsl:variable name="midnightSections" select="local:create-midnightSections-from-timetable(., $microTrainVariant/@departDay, $microTrainVariant/@destDay)"/>
|
|
<xsl:variable name="departureDates" select="$microTrainVariant/departureDate/week/tokenize(., ' ')"/>
|
|
<xsl:for-each select="$midnightSections">
|
|
<xsl:variable name="currentMidnightSection" select="."/>
|
|
<xsl:variable name="dates" select="for $d in $departureDates return shared:shift-day($d, @midnight)"/>
|
|
<xsl:variable name="points"
|
|
select="$timetablePoints/point[(@nodeSequenceNo - $currentMidnightSection/@outNodeSequenceNo ge 0) and ($currentMidnightSection/@inNodeSequenceNo - @nodeSequenceNo ge 0)]"/>
|
|
<xsl:variable name="tractionSections"
|
|
select="$microTrainVariant/tractionSections/tractionSection[(@inNodeSequenceNo - $currentMidnightSection/@outNodeSequenceNo ge 0) and ($currentMidnightSection/@inNodeSequenceNo - @outNodeSequenceNo ge 0)]"/>
|
|
<xsl:variable name="routeEdgeSections"
|
|
select="$microTrainVariant/routeEdgeSections/routeEdgeSection[(@inNodeSequenceNo - $currentMidnightSection/@outNodeSequenceNo ge 0) and ($currentMidnightSection/@inNodeSequenceNo - @outNodeSequenceNo ge 0)][(@inMidnight - $currentMidnightSection/@midnight ge 0) and ($currentMidnightSection/@midnight - @outMidnight ge 0)]"/>
|
|
<xsl:copy>
|
|
<xsl:attribute name="midnight" select="@midnight"/>
|
|
<xsl:element name="date">
|
|
<xsl:sequence select="shared:group-dates-by-week($dates)"/>
|
|
</xsl:element>
|
|
<xsl:element name="timetablePoints">
|
|
<xsl:sequence select="$points"/>
|
|
</xsl:element>
|
|
<xsl:element name="tractionSections">
|
|
<xsl:sequence select="$tractionSections"/>
|
|
</xsl:element>
|
|
<xsl:element name="routeEdgeSections">
|
|
<xsl:sequence select="$routeEdgeSections"/>
|
|
</xsl:element>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:template>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:template mode="group-by-midnight" match="tractionSections|routeEdgeSections"/>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:add-traction-and-routeEdgeSections" as="element(train)">
|
|
<xsl:param name="train" as="element()"/>
|
|
<xsl:apply-templates select="$train" mode="add-traction-and-routeEdgeSections"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:are-routeEdges-needed-for-point" as="xs:boolean">
|
|
<xsl:param name="point" as="element()"/>
|
|
<xsl:for-each select="$point">
|
|
<xsl:choose>
|
|
<xsl:when test="@nodeClass = ('deadEnd', 'endOfModel', 'locationPoint')">
|
|
<xsl:sequence select="true()"/>
|
|
</xsl:when>
|
|
<xsl:when test="@nodeClass = 'stopSignal'">
|
|
<xsl:sequence select="exists(@ptrefId)"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="false()"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:create-midnightSections-from-timetable" as="element(midnightSection)*">
|
|
<xsl:param name="timetablePoints" as="element()"/>
|
|
<xsl:param name="departDay" as="xs:integer"/>
|
|
<xsl:param name="destDay" as="xs:integer"/>
|
|
<xsl:for-each select="$departDay to $destDay">
|
|
<xsl:variable name="midnight" select="."/>
|
|
<xsl:variable name="selectedPoints" select="$timetablePoints/point[./in/@midnight = $midnight or ./out/@midnight = $midnight]"/>
|
|
<xsl:variable name="previousPoint" select="$timetablePoints/point[./in/@midnight - $midnight lt 0 or ./out/@midnight - $midnight lt 0][last()]"/>
|
|
<xsl:variable name="nextPoint" select="$timetablePoints/point[./in/@midnight - $midnight gt 0 or ./out/@midnight - $midnight gt 0][1]"/>
|
|
<xsl:variable name="fromPoint" select="($previousPoint, $selectedPoints[1])[1]"/>
|
|
<xsl:variable name="toPoint" select="($nextPoint, $selectedPoints[last()])[1]"/>
|
|
<xsl:if test="exists($fromPoint) and exists($toPoint)">
|
|
<xsl:sequence select="local:new-midnightSection($fromPoint/@nodeSequenceNo, $toPoint/@nodeSequenceNo, $midnight)"/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:create-routeEdgeSections-from-timetable" as="element(routeEdgeSection)*">
|
|
<xsl:param name="timetablePoints" as="element()"/>
|
|
<xsl:for-each select="$timetablePoints">
|
|
<xsl:variable name="timetablePoints" select="."/>
|
|
<xsl:variable name="relevantPoints"
|
|
select="point[exists(@nodeId)][position() = (1, last()) or exists(./in/routeEdgeRef) or exists(./out/routeEdgeRef)]"/>
|
|
<xsl:variable name="routeEdgeChangePoints"
|
|
select="$relevantPoints[position() = (1, last()) or string-join(./in/routeEdgeRef/@routeEdgeId, ' ') != string-join(./out/routeEdgeRef/@routeEdgeId, ' ')]"/>
|
|
<xsl:for-each select="$routeEdgeChangePoints[position() ne last()]">
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:variable name="outPoint" select="."/>
|
|
<xsl:variable name="inPoint" select="$routeEdgeChangePoints[$index + 1]"/>
|
|
<xsl:variable name="intersection"
|
|
select="local:intersect-routeEdge($timetablePoints/point[(@nodeSequenceNo - $outPoint/@nodeSequenceNo ge 0) and ($inPoint/@nodeSequenceNo - @nodeSequenceNo ge 0)])"/>
|
|
<xsl:sequence select="local:new-routeEdgeSection($outPoint, $inPoint, $intersection/@routeEdgeId)"/>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:create-tractionSections-from-timetable" as="element(tractionSection)*">
|
|
<xsl:param name="timetablePoints" as="element()"/>
|
|
<xsl:variable name="tractionCodeChangePoints" select="$timetablePoints/point[position() = (1, last()) or @motorChange = 'true']"/>
|
|
<xsl:variable name="tractionSections1" as="item()*">
|
|
<xsl:for-each select="$tractionCodeChangePoints[position() ne last()]">
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:variable name="outPoint" select="."/>
|
|
<xsl:variable name="inPoint" select="$tractionCodeChangePoints[$index + 1]"/>
|
|
<xsl:sequence select="local:new-tractionSection($outPoint, $inPoint)"/>
|
|
</xsl:for-each>
|
|
</xsl:variable>
|
|
<xsl:variable name="tractionSections2" select="local:merge-first-and-second-tractionSections($tractionSections1)"/>
|
|
<xsl:sequence select="local:merge-last-and-second-last-tractionSections($tractionSections2)"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:filter-timetablePoints" as="element(train)">
|
|
<xsl:param name="train" as="element()"/>
|
|
<xsl:apply-templates select="$train" mode="filter-timetablePoints"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-course" as="xs:string?">
|
|
<xsl:param name="points" as="element()*"/>
|
|
<xsl:variable name="course"
|
|
select="string-join($points[@nodeClass = ('switch', 'crossing')]/string-join((./in/@port, @nodeName, ./out/@port),'-'), '|')"/>
|
|
<xsl:if test="string-length($course) gt 0">
|
|
<xsl:sequence select="$course"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-microTrainVariant" as="element(train)">
|
|
<xsl:param name="trainXML" as="document-node()"/>
|
|
<xsl:param name="selectionLayer" as="xs:string"/>
|
|
<xsl:param name="creationDate" as="xs:string"/>
|
|
<xsl:param name="purgeDate" as="xs:string"/>
|
|
<xsl:for-each select="$trainXML">
|
|
<xsl:variable name="href" select="file:name(document-uri(.))"/>
|
|
<xsl:for-each select="cern:train">
|
|
<!--<xsl:if test="@trainNo = (123, 521, 544, 33343, 47524)">-->
|
|
<xsl:element name="train">
|
|
<xsl:attribute name="functionalKey" select="local:get-train-functionalKey(@natureCode, @trainNo, @discriminator)"/>
|
|
<xsl:sequence select="@natureCode, @trainNo, @discriminator"/>
|
|
<xsl:attribute name="href" select="$href"/>
|
|
<xsl:attribute name="creationDate" select="$creationDate"/>
|
|
<xsl:for-each select=".//cern:microTrainVariant">
|
|
<xsl:variable name="departureDate" select="shared:get-vector-dates-for-layerVPK(cern:layerVPK, $selectionLayer)"/>
|
|
<xsl:variable name="dateFrom" select="$departureDate[1]"/>
|
|
<xsl:variable name="dateTo" select="$departureDate[last()]"/>
|
|
<xsl:if test="$dateTo ge $purgeDate">
|
|
<xsl:variable name="firstPoint" select="cern:timetablePoints/cern:point[1]"/>
|
|
<xsl:variable name="departDay" select="($firstPoint/cern:in/@midnight, $firstPoint/cern:out/@midnight, 0)[1]"/>
|
|
<xsl:variable name="lastPoint" select="cern:timetablePoints/cern:point[last()]"/>
|
|
<xsl:variable name="destDay" select="($lastPoint/cern:out/@midnight, $lastPoint/cern:in/@midnight, 0)[1]"/>
|
|
<xsl:variable name="macroTrainVariant" select="ancestor::cern:macroTrainVariant"/>
|
|
<xsl:variable name="train" select="ancestor::cern:train"/>
|
|
<xsl:element name="microTrainVariant">
|
|
<xsl:sequence select="@id, @layer"/>
|
|
<xsl:if test="@layer eq 'season'">
|
|
<xsl:sequence select="$macroTrainVariant/@car, $macroTrainVariant/@per"/>
|
|
</xsl:if>
|
|
<xsl:attribute name="dateFrom" select="$dateFrom"/>
|
|
<xsl:attribute name="departDay" select="$departDay"/>
|
|
<xsl:attribute name="dateTo" select="$dateTo"/>
|
|
<xsl:attribute name="destDay" select="$destDay"/>
|
|
<xsl:attribute name="type" select="$train/@type"/>
|
|
<xsl:attribute name="isEmpty" select="($macroTrainVariant/@isEmpty, 'false')[1]"/>
|
|
<xsl:attribute name="trainOperator" select="$macroTrainVariant/@trainOperator"/>
|
|
<xsl:if test="exists($macroTrainVariant/@bulletinName)">
|
|
<xsl:attribute name="bulletinName" select="$macroTrainVariant/@bulletinName"/>
|
|
<xsl:attribute name="bulletinVersionId" select="$macroTrainVariant/@bulletinVersionId"/>
|
|
</xsl:if>
|
|
<xsl:element name="departureDate">
|
|
<xsl:sequence select="shared:group-dates-by-week($departureDate)"/>
|
|
</xsl:element>
|
|
<xsl:apply-templates select="cern:timetablePoints" mode="add-node-and-midnight">
|
|
<xsl:with-param name="departureDate" select="$dateTo" tunnel="yes"/>
|
|
</xsl:apply-templates>
|
|
</xsl:element>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:element>
|
|
<!--</xsl:if>-->
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-node-for-id" as="element()?">
|
|
<xsl:param name="id" as="xs:string?"/>
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:if test="exists($id)">
|
|
<xsl:sequence select="key('by-id', $id, $node-xml)[$date >= @validFromDate and @validToDate >= $date]"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-routeEdgeNodes-for-point" as="element()*">
|
|
<xsl:param name="point" as="element()"/>
|
|
<xsl:for-each select="$point">
|
|
<xsl:if test="local:are-routeEdges-needed-for-point(.)">
|
|
<xsl:variable name="date" select="ancestor::microTrainVariant/@dateFrom"/>
|
|
<xsl:sequence select="local:get-routeEdgeNodes-for-nodeId(@nodeId, $date)"/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-routeEdgeNodes-for-nodeId" as="element()*">
|
|
<xsl:param name="nodeId" as="xs:string"/>
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="key('by-id', $nodeId, $routeEdge-xml)[ancestor::int:routeEdge[$date >= @validFromDate and @validToDate >= $date]]"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:get-train-functionalKey" as="xs:string">
|
|
<xsl:param name="natureCode" as="xs:string?"/>
|
|
<xsl:param name="trainNo" as="xs:integer"/>
|
|
<xsl:param name="discriminator" as="xs:integer?"/>
|
|
<xsl:sequence select="string-join((concat($natureCode, $trainNo), $discriminator),'/')"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:group-by-midnight" as="element(train)">
|
|
<xsl:param name="train" as="element()"/>
|
|
<xsl:apply-templates select="$train" mode="group-by-midnight"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:intersect-routeEdge" as="element()*">
|
|
<xsl:param name="points" as="element()*"/>
|
|
<xsl:variable name="newRouteEdgeRef" as="element()*">
|
|
<xsl:iterate select="$points">
|
|
<xsl:param name="routeEdgeRef" as="element()*"/>
|
|
<xsl:on-completion>
|
|
<xsl:sequence select="$routeEdgeRef"/>
|
|
</xsl:on-completion>
|
|
<xsl:variable name="newRouteEdgeRef"
|
|
select="if (position() eq 1) then out/routeEdgeRef else if (empty(current()/in/routeEdgeRef)) then $routeEdgeRef else $routeEdgeRef[@routeEdgeId = current()/in/routeEdgeRef/@routeEdgeId]"/>
|
|
<xsl:next-iteration>
|
|
<xsl:with-param name="routeEdgeRef" select="$newRouteEdgeRef"/>
|
|
</xsl:next-iteration>
|
|
</xsl:iterate>
|
|
</xsl:variable>
|
|
<xsl:variable name="course" select="local:get-course($points)"/>
|
|
<xsl:sequence select="if (count($newRouteEdgeRef) le 1) then $newRouteEdgeRef else $newRouteEdgeRef[@course eq $course]"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:merge-first-and-second-tractionSections" as="element(tractionSection)*">
|
|
<xsl:param name="tractionSections" as="element(tractionSection)*"/>
|
|
<xsl:choose>
|
|
<xsl:when test="empty($tractionSections[1]/@tractionCode) and exists($tractionSections[2]/@tractionCode)">
|
|
<xsl:sequence select="local:new-tractionSection($tractionSections[1]/@outNodeSequenceNo, $tractionSections[2]/@inNodeSequenceNo, $tractionSections[2]/@tractionCode)"/>
|
|
<xsl:sequence select="$tractionSections[position() gt 2]"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="$tractionSections"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:merge-last-and-second-last-tractionSections" as="element(tractionSection)*">
|
|
<xsl:param name="tractionSections" as="element(tractionSection)*"/>
|
|
<xsl:choose>
|
|
<xsl:when test="empty($tractionSections[last()]/@tractionCode) and exists($tractionSections[last() - 1]/@tractionCode)">
|
|
<xsl:sequence select="$tractionSections[position() lt last() - 1]"/>
|
|
<xsl:sequence
|
|
select="local:new-tractionSection($tractionSections[last() - 1]/@outNodeSequenceNo, $tractionSections[last()]/@inNodeSequenceNo, $tractionSections[last() - 1]/@tractionCode)"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="$tractionSections"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:new-midnightSection" as="element(midnightSection)">
|
|
<xsl:param name="outNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="inNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="midnight" as="xs:integer"/>
|
|
<xsl:element name="midnightSection">
|
|
<xsl:attribute name="outNodeSequenceNo" select="$outNodeSequenceNo"/>
|
|
<xsl:attribute name="inNodeSequenceNo" select="$inNodeSequenceNo"/>
|
|
<xsl:attribute name="midnight" select="$midnight"/>
|
|
</xsl:element>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:new-routeEdgeSection" as="element(routeEdgeSection)">
|
|
<xsl:param name="outPoint" as="element(point)"/>
|
|
<xsl:param name="inPoint" as="element(point)"/>
|
|
<xsl:param name="routeEdgeId" as="xs:string?"/>
|
|
<xsl:variable name="outRouteEdgeRef" select="$outPoint/out/routeEdgeRef[@routeEdgeId eq $routeEdgeId]"/>
|
|
<xsl:variable name="inRouteEdgeRef" select="$inPoint/in/routeEdgeRef[@routeEdgeId eq $routeEdgeId]"/>
|
|
<xsl:variable name="distancesNeeded" select="$outRouteEdgeRef/@distance != 0 or $inRouteEdgeRef/@distance != $inRouteEdgeRef/@length"/>
|
|
<xsl:variable name="fromDistance" select="if ($distancesNeeded) then $outRouteEdgeRef/@distance else ()"/>
|
|
<xsl:variable name="toDistance" select="if ($distancesNeeded) then $inRouteEdgeRef/@distance else ()"/>
|
|
<xsl:sequence
|
|
select="local:new-routeEdgeSection($outPoint/@nodeSequenceNo, $outPoint/out/@midnight, $outPoint/out/@time, $inPoint/@nodeSequenceNo, $inPoint/in/@midnight, $inPoint/in/@time, $routeEdgeId, $fromDistance, $toDistance)"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:new-routeEdgeSection" as="element(routeEdgeSection)">
|
|
<xsl:param name="outNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="outMidnight" as="xs:integer"/>
|
|
<xsl:param name="outTime" as="xs:string"/>
|
|
<xsl:param name="inNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="inMidnight" as="xs:integer"/>
|
|
<xsl:param name="inTime" as="xs:string"/>
|
|
<xsl:param name="routeEdgeId" as="xs:string?"/>
|
|
<xsl:param name="fromDistance" as="xs:integer?"/>
|
|
<xsl:param name="toDistance" as="xs:integer?"/>
|
|
<xsl:element name="routeEdgeSection">
|
|
<xsl:attribute name="outNodeSequenceNo" select="$outNodeSequenceNo"/>
|
|
<xsl:attribute name="outMidnight" select="$outMidnight"/>
|
|
<xsl:attribute name="outTime" select="$outTime"/>
|
|
<xsl:attribute name="inNodeSequenceNo" select="$inNodeSequenceNo"/>
|
|
<xsl:attribute name="inMidnight" select="$inMidnight"/>
|
|
<xsl:attribute name="inTime" select="$inTime"/>
|
|
<xsl:if test="exists($routeEdgeId)">
|
|
<xsl:attribute name="routeEdgeId" select="$routeEdgeId"/>
|
|
</xsl:if>
|
|
<xsl:if test="exists($fromDistance)">
|
|
<xsl:attribute name="fromDistance" select="$fromDistance"/>
|
|
</xsl:if>
|
|
<xsl:if test="exists($toDistance)">
|
|
<xsl:attribute name="toDistance" select="$toDistance"/>
|
|
</xsl:if>
|
|
</xsl:element>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:new-tractionSection" as="element(tractionSection)">
|
|
<xsl:param name="outPoint" as="element(point)"/>
|
|
<xsl:param name="inPoint" as="element(point)"/>
|
|
<xsl:sequence select="local:new-tractionSection($outPoint/@nodeSequenceNo, $inPoint/@nodeSequenceNo, $outPoint/out/@tractionCode)"/>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:new-tractionSection" as="element(tractionSection)">
|
|
<xsl:param name="outNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="inNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="tractionCode" as="xs:string?"/>
|
|
<xsl:element name="tractionSection">
|
|
<xsl:attribute name="outNodeSequenceNo" select="$outNodeSequenceNo"/>
|
|
<xsl:attribute name="inNodeSequenceNo" select="$inNodeSequenceNo"/>
|
|
<xsl:if test="exists($tractionCode)">
|
|
<xsl:attribute name="tractionCode" select="$tractionCode"/>
|
|
</xsl:if>
|
|
</xsl:element>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
<xsl:function name="local:sort-microTrainVariant" as="element()">
|
|
<xsl:param name="train" as="element()"/>
|
|
<xsl:for-each select="$train">
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:perform-sort select="microTrainVariant">
|
|
<xsl:sort select="@layer ne 'season'"/>
|
|
<xsl:sort select="@dateFrom"/>
|
|
</xsl:perform-sort>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
<!-- *********************************************************************************************************** -->
|
|
</xsl:stylesheet>
|