|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<xsl:stylesheet xmlns:arch="http://expath.org/ns/archive"
|
|
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
|
|
xmlns:ext="http://www.infrabel.be/saxon/extension"
|
|
xmlns:file="http://expath.org/ns/file"
|
|
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
|
|
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
|
|
xmlns:saxon="http://saxon.sf.net/"
|
|
xmlns:shared="urn:shared-functions"
|
|
xmlns:thread="java:java.lang.Thread"
|
|
xmlns:uuid="java:java.util.UUID"
|
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
extension-element-prefixes="saxon"
|
|
version="2.0">
|
|
<xsl:import href="/shared/extension-function-api.xslt"/>
|
|
<xsl:variable name="apos" as="xs:string">'</xsl:variable>
|
|
<xsl:variable name="quot" as="xs:string">"</xsl:variable>
|
|
<xsl:variable name="pipe" select="'|'"/>
|
|
<xsl:variable name="separator" select="'-'"/>
|
|
<xsl:variable name="EOL" select="' '"/>
|
|
<xsl:variable name="TAB" select="'	'"/>
|
|
<xsl:variable name="TNO" select="'2078-12-31'"/>
|
|
<xsl:variable name="output-parameters" select="shared:output-parameters()"/>
|
|
<xsl:key name="with-id" match="*" use="@id"/>
|
|
<xsl:key name="with-key" match="*" use="@key"/>
|
|
<xsl:strip-space elements="*"/>
|
|
|
|
<xsl:template mode="shared:copy-no-namespaces" match="@*|*">
|
|
<xsl:copy copy-namespaces="no">
|
|
<xsl:apply-templates select="@*|*" mode="#current"/>
|
|
</xsl:copy>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:acosd" as="xs:double?">
|
|
<xsl:param name="cos" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($cos)) then shared:radians-to-degrees(math:acos($cos)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:add-digest" as="element()*">
|
|
<xsl:param name="element" as="element()*"/>
|
|
<xsl:for-each select="$element">
|
|
<xsl:sequence select="shared:add-or-update-attributes(., 'digest', shared:uuid(.))"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:add-digest-for-element-without-validity" as="element()*">
|
|
<xsl:param name="element" as="element()*"/>
|
|
<xsl:for-each select="$element">
|
|
<xsl:variable name="digest" select="shared:uuid(shared:remove-attributes(., ('validFromDate', 'validToDate')))"/>
|
|
<xsl:sequence select="shared:add-or-update-attributes(., 'digest', $digest)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:add-or-update-attributes">
|
|
<xsl:param name="elements"/>
|
|
<xsl:param name="attrNames"/>
|
|
<xsl:param name="attrValues"/>
|
|
<xsl:for-each select="$elements">
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*[not(name(.) = $attrNames)]"/>
|
|
<xsl:for-each select="$attrNames">
|
|
<xsl:variable name="seq" select="position()"/>
|
|
<xsl:attribute name="{.}" select="$attrValues[$seq]"/>
|
|
</xsl:for-each>
|
|
<xsl:sequence select="node()"/>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:always-false" as="xs:boolean">
|
|
<xsl:sequence select="current-date() lt xs:date('2000-01-01')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:asind" as="xs:double?">
|
|
<xsl:param name="sin" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($sin)) then shared:radians-to-degrees(math:asin($sin)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:atand" as="xs:double?">
|
|
<xsl:param name="tan" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($tan)) then shared:radians-to-degrees(math:atan($tan)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:camel-case" as="xs:string">
|
|
<xsl:param name="arg" as="xs:string?"/>
|
|
<xsl:variable name="camelCaseWords" as="xs:string*">
|
|
<xsl:for-each select="tokenize($arg, '\s+|_|-')">
|
|
<xsl:sequence select="if (position() eq 1) then lower-case(.) else concat(upper-case(substring(., 1, 1)), lower-case(substring(., 2)))"/>
|
|
</xsl:for-each>
|
|
</xsl:variable>
|
|
<xsl:sequence select="string-join($camelCaseWords, '')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:chars" as="xs:string*">
|
|
<!-- Same as functx:chars -->
|
|
<xsl:param name="arg" as="xs:string?"/>
|
|
<xsl:sequence select="for $ch in string-to-codepoints($arg) return codepoints-to-string($ch)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:clone" as="element()*">
|
|
<xsl:param name="pItem" as="element()*"/>
|
|
<xsl:for-each select="$pItem">
|
|
<!-- Delete unwanted namespace nodes like xmlns="" by adding namespace-uri() (e.g. when drawing a graphicalLevelCrossing)
|
|
See http://lenzconsulting.com/namespaces-in-xslt -->
|
|
<xsl:element name="{local-name()}" namespace="{namespace-uri()}">
|
|
<xsl:sequence select="@*"/>
|
|
<xsl:for-each select="*">
|
|
<xsl:sequence select="shared:clone(.)"/>
|
|
</xsl:for-each>
|
|
</xsl:element>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:clone" as="element()*">
|
|
<xsl:param name="pItem" as="element()*"/>
|
|
<xsl:param name="pValidFromDate" as="xs:string?"/>
|
|
<xsl:param name="pValidToDate" as="xs:string?"/>
|
|
<xsl:for-each select="$pItem">
|
|
<xsl:element name="{name()}" namespace="{namespace-uri()}">
|
|
<xsl:sequence select="@* except (@validFromDate, @validToDate)"/>
|
|
<xsl:if test="exists(@validFromDate) and exists($pValidFromDate)">
|
|
<xsl:attribute name="validFromDate" select="shared:max(($pValidFromDate, @validFromDate))"/>
|
|
</xsl:if>
|
|
<xsl:if test="exists(@validToDate) and exists($pValidToDate)">
|
|
<xsl:attribute name="validToDate" select="shared:min(($pValidToDate, @validToDate))"/>
|
|
</xsl:if>
|
|
<xsl:for-each select="*">
|
|
<xsl:sequence select="shared:clone(., $pValidFromDate, $pValidToDate)"/>
|
|
</xsl:for-each>
|
|
</xsl:element>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:compile-stylesheet">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:sequence select="shared:compile-stylesheet($options)"/>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:compile-stylesheet">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Compiling ', $options?stylesheet, ' to ', $options?sef))"/>
|
|
<xsl:variable name="executable" select="shared:find-java()"/>
|
|
<xsl:variable name="arguments" as="xs:string*">
|
|
<xsl:sequence select="'-cp'"/>
|
|
<xsl:sequence select="shared:find-classpath()"/>
|
|
<xsl:sequence select="'net.sf.saxon.Transform'"/>
|
|
<xsl:sequence select="'-target:JS'"/>
|
|
<xsl:sequence select="'-nogo'"/>
|
|
<xsl:sequence select="'-relocate:on'"/>
|
|
<xsl:sequence select="'-ns:##html5'"/>
|
|
<xsl:sequence select="concat('-xsl:', $options?stylesheet)"/>
|
|
<xsl:sequence select="concat('-export:', $options?sef)"/>
|
|
</xsl:variable>
|
|
<saxon:do action="ext:exec-external($executable, $arguments)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:copy">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:if test="file:exists($source)">
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Copying ', $source, ' to ', $target))"/>
|
|
<xsl:sequence select="file:copy($source, $target)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:copy-children">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:if test="file:is-dir($source) and file:is-dir($target)">
|
|
<xsl:for-each select="shared:list($source)">
|
|
<xsl:sequence select="shared:copy(concat($source, .), $target)"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:copy-files">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:if test="file:is-dir($source) and file:is-dir($target)">
|
|
<xsl:for-each select="shared:list-files($source)">
|
|
<xsl:sequence select="shared:copy(concat($source, .), $target)"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:cosd" as="xs:double?">
|
|
<xsl:param name="angleInDegrees" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($angleInDegrees)) then math:cos(shared:degrees-to-radians($angleInDegrees)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:create-dir">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Creating ', $dir))"/>
|
|
<xsl:sequence select="file:create-dir($dir)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:cumulative-sum" as="item()*">
|
|
<xsl:param name="items" as="item()*"/>
|
|
<xsl:sequence select="shared:cumulative-sum-impl($items, 1, 0, ())"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:cumulative-sum-impl" as="item()*">
|
|
<xsl:param name="items" as="item()*"/>
|
|
<xsl:param name="index" as="xs:integer"/>
|
|
<xsl:param name="sum" as="item()"/>
|
|
<xsl:param name="result" as="item()*"/>
|
|
<xsl:variable name="item" as="item()?" select="$items[$index]"/>
|
|
<xsl:choose>
|
|
<xsl:when test="empty($item)">
|
|
<xsl:sequence select="$result"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:variable name="value" select="$item + $sum"/>
|
|
<xsl:variable name="next" select="$result, $value"/>
|
|
<xsl:sequence select="shared:cumulative-sum-impl($items, $index + 1, $value, $next)"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:dates-between" as="xs:string*">
|
|
<xsl:param name="from-date" as="xs:string"/>
|
|
<xsl:param name="to-date" as="xs:string"/>
|
|
<xsl:variable name="nb-of-midnights" select="xs:integer((xs:date($to-date) - xs:date($from-date)) div xs:dayTimeDuration('P1D'))"/>
|
|
<xsl:for-each select="0 to $nb-of-midnights">
|
|
<xsl:sequence select="shared:shift-day($from-date, .)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:day-of-week" as="xs:integer">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="xs:integer(format-date(xs:date($date), '[F1]', (), 'ISO', ()))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:degrees-to-radians" as="xs:double">
|
|
<xsl:param name="angleInDegrees" as="xs:double"/>
|
|
<xsl:sequence select="$angleInDegrees div 180 * math:pi()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:delete">
|
|
<xsl:param name="path" as="xs:string"/>
|
|
<xsl:sequence select="shared:delete($path, true())"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:delete">
|
|
<xsl:param name="path" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:if test="file:exists($path)">
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Deleting ', $path))"/>
|
|
<xsl:sequence select="file:delete($path, $recursive)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:delete-files">
|
|
<xsl:param name="path" as="xs:string"/>
|
|
<xsl:if test="file:is-dir($path)">
|
|
<xsl:for-each select="shared:list-files($path)">
|
|
<xsl:sequence select="shared:delete(concat($path, .))"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:digits-from-string" as="xs:string?">
|
|
<xsl:param name="string" as="xs:string?"/>
|
|
<!-- Double Translate Method first proposed by Michael Kay -->
|
|
<xsl:for-each select="$string">
|
|
<xsl:sequence select="translate(., translate(., '0123456789', ''), '')"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:distinct-sorted-values" as="xs:anyAtomicType*">
|
|
<xsl:param name="sequence" as="xs:anyAtomicType*"/>
|
|
<xsl:param name="data-type" as="xs:string"/>
|
|
<xsl:for-each-group select="$sequence" group-by=".">
|
|
<xsl:sort select="current-grouping-key()" data-type="{$data-type}"/>
|
|
<xsl:sequence select="current-group()[1]"/>
|
|
</xsl:for-each-group>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:doc" as="document-node()?">
|
|
<xsl:param name="uri" as="xs:string"/>
|
|
<xsl:choose>
|
|
<xsl:when test="doc-available($uri)">
|
|
<xsl:sequence select="saxon:discard-document(doc($uri))"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('*** MISSING ', $uri))"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:download">
|
|
<xsl:param name="remoteSource" as="xs:string"/>
|
|
<xsl:param name="localTarget" as="xs:string"/>
|
|
<xsl:param name="hostname" as="xs:string"/>
|
|
<xsl:param name="username" as="xs:string"/>
|
|
<xsl:param name="password" as="xs:string?"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Downloading ', $remoteSource, ' from ', $hostname, ' to ', $localTarget))"/>
|
|
<xsl:sequence select="ext:download($remoteSource, $localTarget, $hostname, $username, $password)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:dummy-doc" as="document-node()">
|
|
<xsl:document>
|
|
<dummy/>
|
|
</xsl:document>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:escape">
|
|
<xsl:param name="text" as="xs:string"/>
|
|
<xsl:sequence select="replace(replace(replace($text, '\|', '-pipe-'), '/', '-slash-'), '\\', '-backslash-')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:extract-nodeIntervals" as="element()*">
|
|
<xsl:param name="entities" as="element()*"/>
|
|
<xsl:param name="minNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="maxNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:variable name="nodeSequenceNos" as="xs:integer*"
|
|
select="$minNodeSequenceNo, sort(distinct-values($entities/(@fromNodeSequenceNo, @toNodeSequenceNo)!xs:integer(.)[. gt $minNodeSequenceNo and . lt $maxNodeSequenceNo])), $maxNodeSequenceNo"/>
|
|
<xsl:for-each select="$nodeSequenceNos">
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:if test="$index ne last()">
|
|
<xsl:sequence select="shared:nodeInterval(., $nodeSequenceNos[$index + 1])"/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:extract-resource">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Extracting resource ', $source, ' to ', $target))"/>
|
|
<xsl:variable name="jar-uri" select="substring-before(static-base-uri(), '/')"/>
|
|
<xsl:variable name="source-uri" select="concat($jar-uri, $source)"/>
|
|
<xsl:sequence select="file:write-binary($target, saxon:read-binary-resource($source-uri))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:extract-valid-from-dates" as="xs:string*">
|
|
<xsl:param name="entityVersions" as="element()*"/>
|
|
<xsl:variable name="validFromDates" as="xs:string*" select="distinct-values($entityVersions/@validFromDate)"/>
|
|
<xsl:variable name="validToDates" as="xs:string*" select="distinct-values($entityVersions/@validToDate[. != $TNO])"/>
|
|
<xsl:variable name="shiftedValidToDates" select="for $date in $validToDates return shared:next-day($date)"/>
|
|
<xsl:sequence select="sort(distinct-values(($validFromDates, $shiftedValidToDates)))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:extract-validities" as="element()*">
|
|
<xsl:param name="entityVersions" as="element()*"/>
|
|
<xsl:variable name="minValidFromDate" select="shared:min($entityVersions/@validFromDate)"/>
|
|
<xsl:variable name="maxValidToDate" select="shared:max($entityVersions/@validToDate)"/>
|
|
<xsl:sequence select="shared:extract-validities($entityVersions, $minValidFromDate, $maxValidToDate)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:extract-validities" as="element()*">
|
|
<xsl:param name="entityVersions" as="element()*"/>
|
|
<xsl:param name="refValidFromDate" as="xs:string"/>
|
|
<xsl:param name="refValidToDate" as="xs:string"/>
|
|
<xsl:variable name="validFromDates" as="xs:string*" select="distinct-values($entityVersions/@validFromDate[. gt $refValidFromDate and . le $refValidToDate])"/>
|
|
<xsl:variable name="validToDates" as="xs:string*" select="distinct-values($entityVersions/@validToDate[. ge $refValidFromDate and . lt $refValidToDate])"/>
|
|
<xsl:variable name="shiftedValidFromDates" as="xs:string*" select="$validFromDates!shared:previous-day(.)"/>
|
|
<xsl:variable name="shiftedValidToDates" as="xs:string*" select="$validToDates!shared:next-day(.)"/>
|
|
<xsl:variable name="mergedValidFromDates" as="xs:string*" select="distinct-values(($refValidFromDate, $validFromDates, $shiftedValidToDates))"/>
|
|
<xsl:variable name="mergedValidToDates" as="xs:string*" select="distinct-values(($refValidToDate, $validToDates, $shiftedValidFromDates))"/>
|
|
<xsl:variable name="dates" as="xs:string*" select="sort(($mergedValidFromDates, $mergedValidToDates))"/>
|
|
<xsl:for-each select="$dates">
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:if test="($index mod 2) = 1">
|
|
<xsl:sequence select="shared:validity(., $dates[$index + 1])"/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:file-extension" as="xs:string?">
|
|
<xsl:param name="uri" as="xs:string?"/>
|
|
<!-- \ escape char in regex is needed for '.' -->
|
|
<xsl:sequence select="tokenize($uri, '\.')[last()]"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:find-classpath" as="xs:string">
|
|
<xsl:sequence select="system-property('java.class.path')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:find-java" as="xs:string">
|
|
<xsl:sequence select="string-join((system-property('java.home'), 'bin', 'java'), system-property('file.separator'))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:fo-to-pdf">
|
|
<xsl:param name="foFileName" as="xs:string"/>
|
|
<xsl:param name="pdfFileName" as="xs:string"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Transforming ', $foFileName, ' to ', $pdfFileName))"/>
|
|
<xsl:sequence select="ext:fo-to-pdf($foFileName, $pdfFileName)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-angle-from-points" as="xs:double">
|
|
<xsl:param name="points" as="xs:double*"/>
|
|
<xsl:variable name="x1" select="$points[1]"/>
|
|
<xsl:variable name="y1" select="$points[2]"/>
|
|
<xsl:variable name="x2" select="$points[3]"/>
|
|
<xsl:variable name="y2" select="$points[4]"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$x1 eq $x2 and $y1 eq $y2">
|
|
<xsl:sequence select="0"/>
|
|
</xsl:when>
|
|
<xsl:when test="$x1 eq $x2 and $y1 ne $y2">
|
|
<xsl:sequence select="-90"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:variable name="tan" select="($y2 - $y1) div ($x2 - $x1)"/>
|
|
<xsl:sequence select="shared:atand($tan)"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-attribute">
|
|
<xsl:param name="element"/>
|
|
<xsl:param name="attrName"/>
|
|
<xsl:for-each select="$element">
|
|
<xsl:sequence select="@*[name(.) = $attrName]"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-nodeIntervals" as="element()*">
|
|
<xsl:param name="nodeRef" as="element()*"/>
|
|
<xsl:param name="entityRefs" as="element()*"/>
|
|
<xsl:sequence select="shared:extract-nodeIntervals($entityRefs, $nodeRef[1]/@sequenceNo, $nodeRef[last()]/@sequenceNo)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-validities" as="element()*">
|
|
<xsl:param name="element" as="element()"/>
|
|
<xsl:param name="entityVersions" as="element()*"/>
|
|
<xsl:for-each select="$element">
|
|
<xsl:sequence select="shared:extract-validities($entityVersions, @validFromDate, @validToDate)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-validities" as="element()*">
|
|
<xsl:param name="element" as="element()"/>
|
|
<xsl:param name="entityVersions" as="element()*"/>
|
|
<xsl:param name="purgeDate" as="xs:string"/>
|
|
<xsl:sequence select="shared:get-validities($element, $entityVersions)[@validToDate ge $purgeDate]"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-vector-bit" as="xs:integer">
|
|
<xsl:param name="vector" as="element()*"/>
|
|
<xsl:param name="layer" as="xs:string"/>
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:variable name="vectorBit" as="xs:string?">
|
|
<xsl:for-each select="$vector">
|
|
<xsl:variable name="refVector" select="@*[local-name() eq concat($layer, 'Vector')]"/>
|
|
<xsl:if test="exists($refVector)">
|
|
<xsl:variable name="dateTo" select="shared:shift-day(@dateFrom, string-length($refVector) - 1)"/>
|
|
<xsl:if test="$date ge @dateFrom and $date le $dateTo">
|
|
<xsl:variable name="index" select="days-from-duration(xs:date($date) - xs:date(@dateFrom)) + 1"/>
|
|
<xsl:sequence select="substring($refVector, $index, 1)"/>
|
|
</xsl:if>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:variable>
|
|
<xsl:sequence select="xs:integer(($vectorBit, '0')[1])"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-vector-dates" as="xs:string*">
|
|
<xsl:param name="vector" as="element()*"/>
|
|
<xsl:param name="layer" as="xs:string"/>
|
|
<xsl:for-each select="$vector">
|
|
<xsl:variable name="refVector" select="@*[local-name() eq concat($layer, 'Vector')]"/>
|
|
<xsl:if test="exists($refVector)">
|
|
<xsl:variable name="dateFrom" select="@dateFrom"/>
|
|
<xsl:variable name="vectorBit" select="shared:chars($refVector)"/>
|
|
<xsl:for-each select="$vectorBit">
|
|
<xsl:sequence select="if (. ne '0') then shared:shift-day($dateFrom, position() - 1) else ()"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:get-vector-dates-for-layerVPK" as="xs:string*">
|
|
<xsl:param name="layerVPK" as="element()"/>
|
|
<xsl:param name="layer" as="xs:string"/>
|
|
<xsl:variable name="refVector" select="$layerVPK/*[local-name() eq concat($layer, 'Layer')]/*:vector"/>
|
|
<xsl:for-each select="$refVector">
|
|
<xsl:variable name="dateFrom" select="@dateFrom"/>
|
|
<xsl:variable name="vectorBit" select="shared:chars(@bitValue)"/>
|
|
<xsl:for-each select="$vectorBit">
|
|
<xsl:sequence select="if (. ne '0') then shared:shift-day($dateFrom, position() - 1) else ()"/>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:group-dates-by-week" as="element(week)*">
|
|
<xsl:param name="date" as="xs:string*"/>
|
|
<xsl:for-each-group select="$date" group-adjacent="shared:week-of-year(.)">
|
|
<xsl:element name="week">
|
|
<xsl:attribute name="id" select="current-grouping-key()"/>
|
|
<xsl:value-of select="current-group()"/>
|
|
</xsl:element>
|
|
</xsl:for-each-group>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:has-result-vector-running-days" as="xs:boolean">
|
|
<xsl:param name="vector" as="element()"/>
|
|
<xsl:sequence select="string-length(translate($vector/@resultVector, '0', '')) gt 0"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:has-validity-overlap" as="xs:boolean">
|
|
<xsl:param name="element-1" as="element()"/>
|
|
<xsl:param name="element-2" as="element()"/>
|
|
<xsl:sequence select="$element-1/(@validToDate, @dateTo, @toDate) ge $element-2/(@validFromDate, @dateFrom, @fromDate) and $element-2/(@validToDate, @dateTo, @toDate) ge $element-1/(@validFromDate, @dateFrom, @fromDate)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:header" as="element()*">
|
|
<xsl:param name="element" as="element()*"/>
|
|
<xsl:for-each select="$element">
|
|
<xsl:copy>
|
|
<xsl:sequence select="@*"/>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:in-filter" as="xs:boolean">
|
|
<xsl:param name="vector" as="element()*"/>
|
|
<xsl:param name="layer" as="xs:string"/>
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:variable name="resultBit" select="shared:get-vector-bit($vector, $layer, $date)"/>
|
|
<xsl:sequence select="$resultBit ne 0"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:is-absolute-uri" as="xs:boolean">
|
|
<xsl:param name="uri" as="xs:string?"/>
|
|
<xsl:sequence select="matches($uri, '^[a-z]+:')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:is-valid" as="xs:boolean">
|
|
<xsl:param name="entity" as="element()"/>
|
|
<xsl:param name="validityDate" as="xs:string?"/>
|
|
<xsl:sequence select="$validityDate ge $entity/@validFromDate and $validityDate le $entity/@validToDate"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:json-to-xml">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:call-template name="shared:write">
|
|
<xsl:with-param name="output" select="shared:json-to-xml($options)"/>
|
|
</xsl:call-template>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:json-to-xml" as="map(*)">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Transforming ', $options?source, ' to ', $options?target))"/>
|
|
<xsl:map-entry key="$options?target">
|
|
<xsl:document>
|
|
<xsl:sequence select="json-to-xml(unparsed-text($options?source))"/>
|
|
</xsl:document>
|
|
</xsl:map-entry>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:key" as="node()*">
|
|
<xsl:param name="key-name" as="xs:string"/>
|
|
<xsl:param name="key-value" as="xs:anyAtomicType*"/>
|
|
<xsl:param name="top" as="node()?"/>
|
|
<xsl:sequence select="$top/key($key-name, $key-value)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:sequence select="shared:list($dir, false(), '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:sequence select="shared:list($dir, $recursive, '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:param name="pattern" as="xs:string"/>
|
|
<xsl:if test="file:exists($dir)">
|
|
<xsl:for-each select="file:list($dir, $recursive, $pattern)">
|
|
<xsl:sort select="."/>
|
|
<xsl:sequence select="translate(., '\', '/')"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-files" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:sequence select="shared:list-files($dir, false(), '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-files" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:sequence select="shared:list-files($dir, $recursive, '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-files" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:param name="pattern" as="xs:string"/>
|
|
<xsl:sequence select="shared:list($dir, $recursive, $pattern)[file:is-file(concat($dir, .))]"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-folders" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:sequence select="shared:list-folders($dir, false(), '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-folders" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:sequence select="shared:list-folders($dir, $recursive, '*')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:list-folders" as="xs:string*">
|
|
<xsl:param name="dir" as="xs:string"/>
|
|
<xsl:param name="recursive" as="xs:boolean"/>
|
|
<xsl:param name="pattern" as="xs:string"/>
|
|
<xsl:sequence select="shared:list($dir, $recursive, $pattern)[file:is-dir(concat($dir, .))]"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:log" as="empty-sequence()">
|
|
<xsl:param name="level" as="xs:string"/>
|
|
<xsl:param name="message" as="item()*"/>
|
|
<xsl:sequence select="ext:log($level, serialize($message))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:log-error" as="empty-sequence()">
|
|
<xsl:param name="description" as="xs:string"/>
|
|
<xsl:param name="module" as="xs:string"/>
|
|
<xsl:param name="line-number" as="xs:integer?"/>
|
|
<xsl:sequence select="shared:log('ERROR', concat('description: ', $description))"/>
|
|
<xsl:sequence select="shared:log('ERROR', concat('module: ', $module))"/>
|
|
<xsl:sequence select="shared:log('ERROR', concat('line-number: ', $line-number))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:log-execution-time" as="empty-sequence()">
|
|
<xsl:param name="startTime" as="xs:dateTime"/>
|
|
<!-- Use xs:dayTimeDuration instead of xs:duration as said in Saxon's documentation -->
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Execution time: ', (saxon:timestamp() - $startTime) div xs:dayTimeDuration('PT1S'), 's'))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:log-stylesheet-params" as="empty-sequence()">
|
|
<xsl:param name="stylesheet-params" as="map(*)?"/>
|
|
<xsl:if test="exists($stylesheet-params)">
|
|
<xsl:for-each select="map:keys($stylesheet-params)">
|
|
<xsl:sort select="string(.)"/>
|
|
<xsl:variable name="value" select="map:get($stylesheet-params, .)"/>
|
|
<xsl:variable name="parameter-value"
|
|
select="
|
|
if (empty($value)) then '()' else
|
|
if ($value instance of map(*)+) then concat('map(#', count($value), ')') else
|
|
if ($value instance of node()) then ($value/saxon:system-id(), path($value))[1] else
|
|
if (contains(lower-case(string(.)), 'password')) then replace($value, '.', '*') else
|
|
string-join($value, ' ')"/>
|
|
<xsl:sequence select="shared:log('INFO', concat($TAB, 'parameter ',., '=',$parameter-value))"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:log-transform-options" as="empty-sequence()">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="source-location" select="map:get($options, 'source-location')"/>
|
|
<xsl:variable name="base-output-uri" select="map:get($options, 'base-output-uri')"/>
|
|
<xsl:variable name="stylesheet-location" select="map:get($options, 'stylesheet-location')"/>
|
|
<xsl:variable name="stylesheet-params" select="map:get($options, 'stylesheet-params')"/>
|
|
<xsl:choose>
|
|
<xsl:when test="exists($source-location) and exists($base-output-uri)">
|
|
<xsl:sequence select="shared:log('INFO', concat('Transforming ',$source-location))"/>
|
|
<xsl:sequence select="shared:log('INFO', concat($TAB, 'into ',$base-output-uri))"/>
|
|
<xsl:sequence select="shared:log('INFO', concat($TAB, 'using ',$stylesheet-location))"/>
|
|
</xsl:when>
|
|
<xsl:when test="exists($source-location) and empty($base-output-uri)">
|
|
<xsl:sequence select="shared:log('INFO', concat('Transforming ',$source-location))"/>
|
|
<xsl:sequence select="shared:log('INFO', concat($TAB, 'using ',$stylesheet-location))"/>
|
|
</xsl:when>
|
|
<xsl:when test="empty($source-location) and exists($base-output-uri)">
|
|
<xsl:sequence select="shared:log('INFO', concat('Generating ',$base-output-uri))"/>
|
|
<xsl:sequence select="shared:log('INFO', concat($TAB, 'using ',$stylesheet-location))"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="shared:log('INFO', concat('Launching ',$stylesheet-location))"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
<xsl:sequence select="shared:log-stylesheet-params($stylesheet-params)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:map-to-json" as="map(*)*">
|
|
<xsl:param name="map" as="map(*)*"/>
|
|
<xsl:for-each select="$map">
|
|
<xsl:variable name="current-map" select="."/>
|
|
<xsl:map>
|
|
<xsl:for-each select="map:keys(.)">
|
|
<xsl:variable name="value" select="$current-map(.)"/>
|
|
<xsl:choose>
|
|
<xsl:when test="count($value) le 1">
|
|
<xsl:map-entry key="." select="$value"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:map-entry key="." select="array{$value}"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:for-each>
|
|
</xsl:map>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:max" as="item()?">
|
|
<xsl:param name="pItems" as="item()*"/>
|
|
<xsl:for-each select="$pItems">
|
|
<xsl:sort select="." order="descending"/>
|
|
<xsl:if test="position() eq 1">
|
|
<xsl:sequence select="."/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:merge-versions" as="element()*">
|
|
<xsl:param name="versions" as="element()*"/>
|
|
<xsl:variable name="versions-xml">
|
|
<xsl:sequence select="$versions"/>
|
|
</xsl:variable>
|
|
<xsl:for-each-group select="$versions-xml/*" group-starting-with="*[not(preceding-sibling::*[1]/@digest = @digest and shared:next-day(preceding-sibling::*[1]/@validToDate) = @validFromDate)]">
|
|
<xsl:choose>
|
|
<xsl:when test="count(current-group()) = 1">
|
|
<xsl:sequence select="current-group()"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:variable name="newValidFromDate" select="current-group()[1]/@validFromDate"/>
|
|
<xsl:variable name="newValidToDate" select="current-group()[last()]/@validToDate"/>
|
|
<xsl:sequence select="shared:add-or-update-attributes(current-group()[1], ('validFromDate', 'validToDate'), ($newValidFromDate, $newValidToDate))"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:for-each-group>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:merge-versions-without-digest" as="element()*">
|
|
<xsl:param name="versions" as="element()*"/>
|
|
<xsl:choose>
|
|
<xsl:when test="count($versions) le 1">
|
|
<xsl:sequence select="$versions"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:variable name="versionsWithDigest" select="shared:add-digest-for-element-without-validity($versions)"/>
|
|
<xsl:variable name="mergedVersions" select="shared:merge-versions($versionsWithDigest)"/>
|
|
<xsl:sequence select="shared:remove-attributes($mergedVersions, 'digest')"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:min" as="item()?">
|
|
<xsl:param name="pItems" as="item()*"/>
|
|
<xsl:for-each select="$pItems">
|
|
<xsl:sort select="." order="ascending"/>
|
|
<xsl:if test="position() eq 1">
|
|
<xsl:sequence select="."/>
|
|
</xsl:if>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:month-of-year" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="format-date(xs:date($date), '[Y]-[M,2]')"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:move" as="empty-sequence()">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:if test="file:exists($source) and $source ne $target">
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Moving ', $source, ' to ', $target))"/>
|
|
<xsl:sequence select="file:move($source, $target)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:move-files">
|
|
<xsl:param name="source" as="xs:string"/>
|
|
<xsl:param name="target" as="xs:string"/>
|
|
<xsl:if test="file:is-dir($source) and file:is-dir($target)">
|
|
<xsl:for-each select="shared:list-files($source)">
|
|
<xsl:sequence select="shared:move(concat($source, .), $target)"/>
|
|
</xsl:for-each>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:next-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="shared:shift-day($date, 1)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:nodeInterval" as="element()">
|
|
<xsl:param name="fromNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:param name="toNodeSequenceNo" as="xs:integer"/>
|
|
<xsl:element name="nodeInterval">
|
|
<xsl:attribute name="fromNodeSequenceNo" select="$fromNodeSequenceNo"/>
|
|
<xsl:attribute name="toNodeSequenceNo" select="$toNodeSequenceNo"/>
|
|
</xsl:element>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:open-file" as="node()?">
|
|
<xsl:param name="pathAndFileName" as="xs:string?"/>
|
|
<xsl:for-each select="$pathAndFileName">
|
|
<xsl:variable name="uri" select="shared:path-to-uri(.)"/>
|
|
<xsl:sequence select="shared:doc($uri)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:open-file" as="document-node()?">
|
|
<xsl:param name="baseURI" as="xs:string?"/>
|
|
<xsl:param name="fileName" as="xs:string?"/>
|
|
<xsl:if test="exists($baseURI) and exists($fileName)">
|
|
<xsl:variable name="pathAndFileName" select="concat($baseURI, $fileName)"/>
|
|
<xsl:sequence select="shared:open-file($pathAndFileName)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:open-file-without-logging" as="document-node()?">
|
|
<xsl:param name="pathAndFileName" as="xs:string"/>
|
|
<xsl:variable name="uri" select="shared:path-to-uri($pathAndFileName)"/>
|
|
<xsl:sequence select="if (doc-available($uri)) then saxon:discard-document(doc($uri)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:open-file-without-logging" as="document-node()?">
|
|
<xsl:param name="baseURI" as="xs:string?"/>
|
|
<xsl:param name="fileName" as="xs:string?"/>
|
|
<xsl:if test="exists($baseURI) and exists($fileName)">
|
|
<xsl:variable name="pathAndFileName" select="concat($baseURI, $fileName)"/>
|
|
<xsl:sequence select="shared:open-file-without-logging($pathAndFileName)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:open-files" as="document-node()*">
|
|
<xsl:param name="baseURI" as="xs:string"/>
|
|
<xsl:param name="pattern" as="xs:string"/>
|
|
<xsl:variable name="uri" select="shared:path-to-uri($baseURI)"/>
|
|
<xsl:variable name="files" select="collection(concat($uri, '?select=', $pattern))"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Nb of loaded files = ', count($files)))"/>
|
|
<xsl:for-each select="$files">
|
|
<xsl:sort select="saxon:system-id()"/>
|
|
<xsl:sequence select="saxon:discard-document(.)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:output-parameters" as="map(*)">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'xml'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'xml'"/>
|
|
<xsl:map-entry key="'omit-xml-declaration'" select="false()"/>
|
|
<xsl:map-entry key="'indent'" select="true()"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'indent-spaces')" select="0"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'line-length')" select="100000"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'attribute-order')" select="'*'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'uuid'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'xml'"/>
|
|
<xsl:map-entry key="'omit-xml-declaration'" select="true()"/>
|
|
<xsl:map-entry key="'indent'" select="true()"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'indent-spaces')" select="0"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'line-length')" select="100000"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'attribute-order')" select="'*'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'html'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'html'"/>
|
|
<xsl:map-entry key="'indent'" select="true()"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'indent-spaces')" select="0"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'line-length')" select="100000"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'attribute-order')" select="'*'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'xhtml'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'xhtml'"/>
|
|
<xsl:map-entry key="'indent'" select="true()"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'indent-spaces')" select="0"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'line-length')" select="100000"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'attribute-order')" select="'*'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'json'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'json'"/>
|
|
<xsl:map-entry key="QName('http://saxon.sf.net/', 'property-order')" select="'*'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'txt'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'text'"/>
|
|
<xsl:map-entry key="'byte-order-mark'" select="true()"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'csv'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'text'"/>
|
|
<xsl:map-entry key="'byte-order-mark'" select="true()"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
<xsl:map-entry key="'hkt'">
|
|
<xsl:map>
|
|
<xsl:map-entry key="'method'" select="'text'"/>
|
|
</xsl:map>
|
|
</xsl:map-entry>
|
|
</xsl:map>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:output-parameters-for-uri" as="map(*)">
|
|
<xsl:param name="uri" as="xs:string?"/>
|
|
<xsl:sequence select="($output-parameters(lower-case(shared:file-extension($uri))), $output-parameters?xml)[1]"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:path-to-uri" as="xs:string">
|
|
<xsl:param name="path" as="xs:string"/>
|
|
<xsl:sequence select="file:path-to-uri($path)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:path-to-uri" as="xs:string">
|
|
<xsl:param name="baseURI" as="xs:string"/>
|
|
<xsl:param name="fileName" as="xs:string"/>
|
|
<xsl:variable name="path" select="concat($baseURI, $fileName)"/>
|
|
<xsl:sequence select="file:path-to-uri($path)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:pdf-to-layer">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:sequence select="shared:pdf-to-layer($options)"/>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:pdf-to-layer">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="n" select="count($options?inputFileName)"/>
|
|
<xsl:sequence select="shared:log('DEBUG', string-join(('Transforming', $n, 'pdf''s to 1 pdf', $options?outputFileName, 'with', $n, 'layers', $options?layerName), ' '))"/>
|
|
<saxon:do action="ext:pdf-to-layer($options?inputFileName, $options?layerName, $options?layerOn, $options?outputFileName)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:previous-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="shared:shift-day($date, -1)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:radians-to-degrees" as="xs:double">
|
|
<xsl:param name="angleInRadians" as="xs:double"/>
|
|
<xsl:sequence select="$angleInRadians div math:pi() * 180"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:remove-attributes" as="element()*">
|
|
<xsl:param name="elements" as="element()*"/>
|
|
<xsl:param name="names" as="xs:string*"/>
|
|
<xsl:for-each select="$elements">
|
|
<xsl:copy>
|
|
<xsl:sequence select="(@*[not(name() = $names)], node())"/>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:serialize-map" as="xs:string*">
|
|
<xsl:param name="map" as="map(*)*"/>
|
|
<xsl:for-each select="$map">
|
|
<xsl:sequence select="serialize(shared:map-to-json(.), $output-parameters?json)"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:shift-day" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:param name="nbOfDays" as="xs:integer"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$nbOfDays gt 0">
|
|
<!-- Add abs to avoid compilation warning -->
|
|
<xsl:value-of select="xs:date($date) + xs:dayTimeDuration(concat('P', abs($nbOfDays), 'D'))"/>
|
|
</xsl:when>
|
|
<xsl:when test="$nbOfDays lt 0">
|
|
<xsl:value-of select="xs:date($date) - xs:dayTimeDuration(concat('P', abs($nbOfDays), 'D'))"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:value-of select="$date"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:sind" as="xs:double?">
|
|
<xsl:param name="angleInDegrees" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($angleInDegrees)) then math:sin(shared:degrees-to-radians($angleInDegrees)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:sleep">
|
|
<xsl:param name="seconds" as="xs:integer"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Sleeping for ', $seconds, ' seconds...'))"/>
|
|
<xsl:sequence select="thread:sleep(1000*$seconds)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:svg-to-bbox" as="map(*)*">
|
|
<xsl:param name="svgUri" as="xs:string"/>
|
|
<xsl:sequence select="shared:svg-to-bbox($svgUri, ())"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:svg-to-bbox" as="map(*)*">
|
|
<xsl:param name="svgUri" as="xs:string"/>
|
|
<xsl:param name="queryId" as="xs:string*"/>
|
|
<xsl:variable name="response" select="ext:svg-to-bbox($svgUri, $queryId)"/>
|
|
<xsl:sequence select="shared:log('DEBUG', $response)"/>
|
|
<xsl:sequence select="array:flatten(parse-json($response))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:tand" as="xs:double?">
|
|
<xsl:param name="angleInDegrees" as="xs:double?"/>
|
|
<xsl:sequence select="if (exists($angleInDegrees)) then math:tan(shared:degrees-to-radians($angleInDegrees)) else ()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:to-folder" as="xs:string?">
|
|
<xsl:param name="property" as="xs:string?"/>
|
|
<xsl:for-each select="normalize-space($property)[string-length() gt 0]">
|
|
<xsl:for-each select="translate(., '\', '/')">
|
|
<xsl:sequence select="if (ends-with(., '/')) then . else concat(., '/')"/>
|
|
</xsl:for-each>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:total-minutes-from-time" as="xs:integer">
|
|
<xsl:param name="time" as="xs:string"/>
|
|
<!-- hours-from-time() returns 0 for 24:00:00 -->
|
|
<xsl:sequence select="60*xs:integer(substring($time, 1, 2)) + minutes-from-time(xs:time($time))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:transform">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:variable name="extended-options" select="map:merge((map:entry('delivery-format', 'serialized'), $options))"/>
|
|
<xsl:call-template name="shared:write">
|
|
<xsl:with-param name="output" select="shared:transform($extended-options)"/>
|
|
</xsl:call-template>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:transform" as="map(*)">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:sequence select="shared:log-transform-options($options)"/>
|
|
<xsl:sequence select="transform($options)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:transform-with-saxon">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:call-template name="shared:write">
|
|
<xsl:with-param name="output" select="shared:transform-with-saxon($options)"/>
|
|
</xsl:call-template>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:transform-with-saxon" as="map(*)">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:sequence select="shared:log-transform-options($options)"/>
|
|
<xsl:variable name="stylesheet" select="saxon:compile-stylesheet(doc($options?stylesheet-location))"/>
|
|
<xsl:variable name="source"
|
|
select="if (exists($options?source-node)) then $options?source-node else if (exists($options?source-location)) then shared:doc($options?source-location) else shared:dummy-doc()"/>
|
|
<xsl:variable name="output-document" as="document-node()?" select="saxon:transform($stylesheet, $source, $options?stylesheet-params)"/>
|
|
<xsl:variable name="base-output-uri" select="($options?base-output-uri, 'output')[1]"/>
|
|
<xsl:variable name="serialization-params" select="shared:output-parameters-for-uri($base-output-uri)"/>
|
|
<xsl:map-entry key="$base-output-uri" select="serialize($output-document, $serialization-params)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:unzip">
|
|
<xsl:param name="source-file" as="xs:string"/>
|
|
<xsl:param name="target-folder" as="xs:string"/>
|
|
<!-- Code inspired by arch:to-files(), see http://expath.org/spec/archive/editor#fn.to.files Archive Module, EXPath Candidate Module 12 May 2014 -->
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Unzipping ', $source-file, ' to ', $target-folder))"/>
|
|
<xsl:variable name="archive" select="file:read-binary($source-file)"/>
|
|
<xsl:variable name="entries" select="arch:entries($archive)"/>
|
|
<xsl:variable name="dirs" select="$entries[ends-with(., '/')]"/>
|
|
<xsl:for-each select="$dirs">
|
|
<xsl:sequence select="file:create-dir(concat($target-folder, .))"/>
|
|
</xsl:for-each>
|
|
<!-- Tuning: extract all binary data in one call -->
|
|
<xsl:variable name="files" select="$entries except $dirs"/>
|
|
<xsl:variable name="binary-data" select="arch:extract-binary($archive, $files)"/>
|
|
<xsl:for-each select="$files">
|
|
<xsl:variable name="index" select="position()"/>
|
|
<xsl:sequence select="file:write-binary(concat($target-folder, .), $binary-data[$index])"/>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:unzip-ext">
|
|
<xsl:param name="source-file" as="xs:string"/>
|
|
<xsl:param name="target-folder" as="xs:string"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Unzipping ', $source-file, ' to ', $target-folder))"/>
|
|
<xsl:sequence select="ext:unzip($source-file, $target-folder)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:uuid" as="xs:string">
|
|
<xsl:param name="element" as="item()*"/>
|
|
<xsl:sequence select="ext:UUID(serialize($element, $output-parameters?uuid))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:uuid-new" as="xs:string">
|
|
<xsl:param name="element" as="item()*"/>
|
|
<xsl:sequence select="uuid:nameUUIDFromBytes(string-to-codepoints(serialize($element, $output-parameters?uuid))!xs:unsignedByte(.))?toString()"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:week-of-year" as="xs:string">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:variable name="day-of-week" select="shared:day-of-week($date)"/>
|
|
<xsl:variable name="ref-Thursday" select="xs:date(shared:shift-day($date, 4 - $day-of-week))"/>
|
|
<xsl:sequence select="format-date($ref-Thursday, '[Y]-[W,2]', (), 'ISO', ())"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:validate">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:variable name="startTime" select="saxon:timestamp()"/>
|
|
<xsl:sequence select="$startTime[shared:always-false()]"/>
|
|
<xsl:sequence select="shared:validate($options)"/>
|
|
<xsl:sequence select="shared:log-execution-time($startTime)"/>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:validate">
|
|
<xsl:param name="options" as="map(*)"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Validating ', $options?xml, ' with ', $options?xsd))"/>
|
|
<xsl:sequence select="ext:validate($options?xml, $options?xsd)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:validity" as="element()?">
|
|
<xsl:param name="validFromDate" as="xs:string"/>
|
|
<xsl:param name="validToDate" as="xs:string"/>
|
|
<xsl:if test="$validFromDate le $validToDate">
|
|
<xsl:element name="validity">
|
|
<xsl:attribute name="validFromDate" select="$validFromDate"/>
|
|
<xsl:attribute name="validToDate" select="$validToDate"/>
|
|
</xsl:element>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:validity-intersection" as="element()?">
|
|
<xsl:param name="element-1" as="element()"/>
|
|
<xsl:param name="element-2" as="element()"/>
|
|
<xsl:variable name="validFromDate" select="max(($element-1, $element-2)/(@validFromDate, @dateFrom, @fromDate)!string())"/>
|
|
<xsl:variable name="validToDate" select="min(($element-1, $element-2)/(@validToDate, @dateTo, @toDate)!string())"/>
|
|
<xsl:sequence select="shared:validity($validFromDate, $validToDate)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:template name="shared:write">
|
|
<xsl:param name="output" as="map(*)"/>
|
|
<xsl:for-each select="map:keys($output)">
|
|
<xsl:sort select="."/>
|
|
<xsl:sequence select="shared:write(., map:get($output, .))"/>
|
|
</xsl:for-each>
|
|
</xsl:template>
|
|
|
|
<xsl:function name="shared:write">
|
|
<xsl:param name="href" as="xs:string"/>
|
|
<xsl:param name="value" as="xs:string"/>
|
|
<!-- Exclude default added "output" when base-output-uri is absent by checking is-absolute-uri() -->
|
|
<xsl:if test="shared:is-absolute-uri($href)">
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Exporting ', $href))"/>
|
|
<xsl:sequence select="file:write-text($href, $value)"/>
|
|
</xsl:if>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:zip">
|
|
<xsl:param name="source-folder" as="xs:string"/>
|
|
<xsl:param name="target-file" as="xs:string"/>
|
|
<xsl:sequence select="shared:zip($source-folder, '', $target-file)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:zip">
|
|
<xsl:param name="source-folder" as="xs:string"/>
|
|
<xsl:param name="source-files" as="xs:string*"/>
|
|
<xsl:param name="target-file" as="xs:string"/>
|
|
<!-- Code inspired by arch:from-files(), see http://expath.org/spec/archive/editor#fn.from.files Archive Module, EXPath Candidate Module 12 May 2014 -->
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Zipping ', $source-folder, ' to ', $target-file))"/>
|
|
<xsl:variable name="absolute.files" select="for $f in $source-files return concat($source-folder, $f)"/>
|
|
<xsl:variable name="all" as="xs:string*" select="for $f in $absolute.files return if(file:is-dir($f)) then (for $f1 in shared:list($f,true()) return concat($f,$f1)) else $f"/>
|
|
<xsl:variable name="content" as="xs:base64Binary*" select="for $f in $all return if(file:is-dir($f)) then xs:base64Binary('') else file:read-binary($f)"/>
|
|
<xsl:variable name="relative.names" select="for $n in $all return replace($n, $source-folder, '')"/>
|
|
<xsl:variable name="archive" select="arch:create($relative.names, $content)"/>
|
|
<xsl:sequence select="file:write-binary($target-file, $archive)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="shared:zip-ext">
|
|
<xsl:param name="source-folder" as="xs:string"/>
|
|
<xsl:param name="target-file" as="xs:string"/>
|
|
<xsl:sequence select="shared:log('DEBUG', concat('Zipping ', $source-folder, ' to ', $target-file))"/>
|
|
<xsl:sequence select="ext:zip($source-folder, $target-file)"/>
|
|
</xsl:function>
|
|
|
|
</xsl:stylesheet>
|