|
<?xml version="1.0" encoding="UTF-8" ?>
|
|
|
|
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
|
xmlns:udf="user-defined"
|
|
xmlns:fn="http://www.w3.org/2005/xpath-functions"
|
|
xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
|
|
xmlns:err="http://www.w3.org/2005/xqt-errors"
|
|
xmlns:math="http://exslt.org/math"
|
|
xmlns:saxon="http://saxon.sf.net/"
|
|
xmlns:exsl="http://exslt.org/common"
|
|
xmlns:date="http://exslt.org/dates-and-times"
|
|
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
|
|
exclude-result-prefixes="xs xdt udf saxon math fn err exsl date">
|
|
<xsl:key name="FRF.key" match="//fact/@RFR.fact" use="../@factID"/>
|
|
|
|
<xsl:function name="udf:GBT_String" as="xs:string">
|
|
<xsl:param name="seq" as="xs:string+"/>
|
|
<xsl:param name="threshold" as="xs:string"/>
|
|
<xsl:param name="backstop" as="xs:string"/>
|
|
<xsl:choose>
|
|
<xsl:when test="$threshold lt $seq[1]">
|
|
<xsl:sequence select="$backstop"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:iterate select="$seq">
|
|
<xsl:variable name="pos" select="position()"/>
|
|
<xsl:if test=". gt $threshold">
|
|
<xsl:sequence select="$seq[$pos - 1]"/>
|
|
<xsl:break/>
|
|
</xsl:if>
|
|
<xsl:on-completion>
|
|
<xsl:sequence select="$seq[last()]"/>
|
|
</xsl:on-completion>
|
|
</xsl:iterate>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:in-date-range">
|
|
<xsl:param name="date"/>
|
|
<xsl:param name="range.start"/>
|
|
<xsl:param name="range.end"/>
|
|
<xsl:sequence select="boolean((xs:date($date) ge xs:date($range.start)) and (xs:date($date) le xs:date($range.end)))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:CurrentOpState" as="xs:string">
|
|
<xsl:param name="id" as="xs:string"/>
|
|
<xsl:param name="map" as="map(*)"/>
|
|
<xsl:param name="timeStamp" as="xs:dateTime"/>
|
|
<xsl:variable name="FRF_id" select="key('FRF.key',$id,document('Fact2FRF_Lookup.xml'))"/>
|
|
<xsl:variable name="keys" select="if(empty($map($FRF_id))) then '0' else map:keys($map($FRF_id))"/>
|
|
<xsl:variable name="key.key" select="udf:GBT_String($keys,concat($FRF_id,'==',$timeStamp),'UNASSESSED')"/>
|
|
<xsl:choose>
|
|
<xsl:when test="not($FRF_id = map:keys($map))">
|
|
<xsl:sequence select="'UNASSESSED'"/>
|
|
</xsl:when>
|
|
<xsl:when test="count($map($FRF_id)) = 0">
|
|
<xsl:sequence select="'UNASSESSED'"/>
|
|
</xsl:when>
|
|
<xsl:when test="$key.key='UNASSESSED'">
|
|
<xsl:sequence select="'UNASSESSED'"/>
|
|
</xsl:when>
|
|
<xsl:when test="count(map:get($map($FRF_id),$key.key)[last()]/@operationalState) ne 1">
|
|
<xsl:message terminate="yes">
|
|
<xsl:text>
|
|
</xsl:text>
|
|
$FRF_id, $id, timestamp
|
|
<xsl:value-of select="$FRF_id, $id, $timeStamp"/>
|
|
<xsl:text>
|
|
</xsl:text>
|
|
key.key
|
|
<xsl:value-of select="$key.key"/>
|
|
<xsl:text>
|
|
</xsl:text>
|
|
map:keys($map($FRF_id))
|
|
<xsl:for-each select="map:keys($map($FRF_id))">
|
|
<xsl:text>
|
|
</xsl:text>
|
|
<xsl:copy-of select="."/>
|
|
<xsl:text>nodes
|
|
</xsl:text>
|
|
<xsl:copy-of select="map:get($map($FRF_id),current())"/>
|
|
<xsl:text>count
|
|
</xsl:text>
|
|
</xsl:for-each>
|
|
<xsl:text>
|
|
</xsl:text>
|
|
map:get($map($FRF_id),$key.key)
|
|
<xsl:for-each select="map:get($map($FRF_id),$key.key)">
|
|
<xsl:text>
|
|
</xsl:text>
|
|
<xsl:copy-of select="."/>
|
|
</xsl:for-each>
|
|
</xsl:message>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="map:get($map($FRF_id),$key.key)[last()]/@operationalState"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:sign">
|
|
<xsl:param name="arg"/>
|
|
<xsl:sequence select="if ($arg=0) then 0 else if (+$arg gt 0) then 1 else -1"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:dTs" as="xs:dateTime">
|
|
<xsl:param name="dT" as="xs:string"/>
|
|
<xsl:sequence select="xs:dateTime(concat(substring(normalize-space($dT),7,4),'-',substring(normalize-space($dT),1,2),'-',substring(normalize-space($dT),4,2),'T',substring(normalize-space($dT),12,8)))
|
|
"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:date" as="xs:date">
|
|
<xsl:param name="date" as="xs:string"/>
|
|
<xsl:sequence select="xs:date(date:date($date))"/>
|
|
</xsl:function>
|
|
|
|
|
|
<xsl:function name="udf:duration" as="xs:dayTimeDuration">
|
|
<xsl:param name="dTD" as="xs:string"/>
|
|
<xsl:sequence select="xs:dayTimeDuration(concat('PT',substring(normalize-space($dTD),1,2),'H',substring(normalize-space($dTD),4,2),'M',substring(normalize-space($dTD),7,2),'S'))
|
|
"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:median" as="xs:double">
|
|
<xsl:param name="values" as="xs:double+"/>
|
|
<xsl:choose>
|
|
<xsl:when test="count($values) mod 2 = 0">
|
|
<xsl:sequence select="avg(saxon:sort($values)[(position() eq count($values) div 2) or (position() eq count($values) div 2 + 1)])"/>
|
|
</xsl:when>
|
|
<xsl:otherwise>
|
|
<xsl:sequence select="saxon:sort($values)[position() eq (count($values) idiv 2 + 1)]"/>
|
|
</xsl:otherwise>
|
|
</xsl:choose>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:grade.maker" as="xs:double">
|
|
<xsl:param name="start.date"/>
|
|
<xsl:param name="initial.grade"/>
|
|
<xsl:param name="evaluation.date"/>
|
|
<xsl:sequence select="$initial.grade - 1 + floor((xs:date($evaluation.date) - xs:date('2010-07-15')) div xs:dayTimeDuration('P365DT6H'))
|
|
- floor((xs:date($start.date) - xs:date('2010-07-15')) div xs:dayTimeDuration('P365DT6H'))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:NG_grade.maker" as="xs:double">
|
|
<xsl:param name="start.date" as="xs:string"/>
|
|
<xsl:param name="initial.grade" as="xs:integer"/>
|
|
<xsl:param name="evaluation.date" as="xs:string"/>
|
|
<xsl:sequence select="$initial.grade - 1 + floor((xs:date($evaluation.date) - xs:date('2010-07-15')) div xs:dayTimeDuration('P365DT6H'))
|
|
- floor((xs:date($start.date) - xs:date('2010-07-15')) div xs:dayTimeDuration('P365DT6H'))"/>
|
|
</xsl:function>
|
|
|
|
|
|
<xsl:function name="udf:round" as="xs:double">
|
|
<xsl:param name="x" as="xs:double"/>
|
|
<xsl:param name="n" as="xs:integer"/>
|
|
<xsl:sequence select="round(math:power(10,$n) * $x) div math:power(10, $n)"/>
|
|
</xsl:function>
|
|
|
|
|
|
<xsl:function name="udf:percentile">
|
|
<xsl:param name="values" as="xs:double*"/>
|
|
<xsl:param name="cut" as="xs:double"/>
|
|
|
|
<xsl:variable name="rank" select="(count($values) + 1) * $cut div 100"/>
|
|
<xsl:variable name="sorted.values" select="saxon:sort($values)"/>
|
|
<xsl:variable name="aug.values" select="($sorted.values[1],$sorted.values,$sorted.values[last()])"/>
|
|
<xsl:variable name="cut1" select="$aug.values[floor($rank) + 1]"/>
|
|
<xsl:variable name="cut2" select="$aug.values[floor($rank) + 2]"/>
|
|
<xsl:variable name="man" select="$rank - floor($rank)"/>
|
|
|
|
<xsl:sequence select="$man*$cut2 + (1-$man)*$cut1"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:session.sorter">
|
|
<xsl:param name="sessions" as="element(session)*"/>
|
|
<xsl:sequence select="saxon:sort($sessions,function($x) as xs:dateTime {udf:dTs($x/@startedOn)})"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:NG_session.sorter">
|
|
<xsl:param name="sessions" as="element(session)*"/>
|
|
<xsl:sequence select="saxon:sort($sessions,function($x) as xs:dateTime {xs:dateTime($x/@startedOn)})"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:get.fact.from.session" as="document-node()">
|
|
<xsl:param name="session.file" as="document-node()"/>
|
|
<xsl:copy-of select="saxon:discard-document(document(replace(base-uri($session.file),'_session_','_fact_')))"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:csv.import.headers">
|
|
<xsl:param name="textStream" as="xs:string"/>
|
|
<xsl:param name="separator" as="xs:string"/>
|
|
<xsl:variable name="table">
|
|
<xsl:analyze-string select="$textStream" regex="\r\n">
|
|
<xsl:non-matching-substring>
|
|
<xsl:text>
|
|
</xsl:text>
|
|
<row>
|
|
<xsl:analyze-string select="if (matches(.,'^.+,$')) then . else concat(.,',')" regex='("([^"]*?)")|([^,]*?),'>
|
|
<xsl:matching-substring>
|
|
<cell>
|
|
<xsl:sequence select="regex-group(2)"/>
|
|
<xsl:sequence select="regex-group(3)"/>
|
|
</cell>
|
|
</xsl:matching-substring>
|
|
</xsl:analyze-string>
|
|
</row>
|
|
</xsl:non-matching-substring>
|
|
</xsl:analyze-string>
|
|
</xsl:variable>
|
|
<xsl:variable name="headers" select="for $r in $table/row[1]/cell return normalize-space($r)"/>
|
|
<xsl:variable name="column.count" select="max(for $r in $table/row return count($r/cell))"/>
|
|
<xsl:if test="$column.count ne count(distinct-values($headers))">
|
|
<xsl:message terminate="yes">
|
|
Not enough unique headers in csv import.
|
|
Headers = <xsl:value-of select="$headers"/>
|
|
Column Count = <xsl:value-of select="$column.count"/>
|
|
</xsl:message>
|
|
</xsl:if>
|
|
<xsl:text>
|
|
</xsl:text>
|
|
<table>
|
|
<xsl:for-each select="$table/row[position() gt 1]">
|
|
<xsl:text>
|
|
</xsl:text>
|
|
<row>
|
|
<xsl:for-each select="cell">
|
|
<xsl:variable name="column" select="position()"/>
|
|
<xsl:attribute name="{$headers[position() = $column]}" select="."/>
|
|
</xsl:for-each>
|
|
<xsl:if test="count(cell) lt count($headers)">
|
|
<xsl:attribute name="{$headers[position() = count($headers)]}" select="''"/>
|
|
</xsl:if>
|
|
</row>
|
|
</xsl:for-each>
|
|
</table>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:write-out">
|
|
<xsl:param name="tree"/>
|
|
<xsl:copy-of select="udf:write-out-guts($tree,1)"/>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:write-out-guts">
|
|
<xsl:param name="tree"/>
|
|
<xsl:param name="level"/>
|
|
<xsl:for-each select="$tree">
|
|
<xsl:copy>
|
|
<xsl:copy-of select="@*"/>
|
|
<xsl:for-each select="$tree/child::node()">
|
|
<xsl:text>
|
|
</xsl:text><xsl:value-of select="for $i in 1 to $level return '	'"/>
|
|
<xsl:copy-of select="udf:write-out-guts(.,$level + 1)"/>
|
|
</xsl:for-each>
|
|
<xsl:text>
|
|
</xsl:text><xsl:value-of select="for $i in 1 to ($level - 1) return '	'"/>
|
|
</xsl:copy>
|
|
</xsl:for-each>
|
|
</xsl:function>
|
|
|
|
<xsl:function name="udf:FRF_Lookup" saxon:memo-function="yes">
|
|
<xsl:param name="id" as="xs:string"/>
|
|
<xsl:sequence select="key('FRF.key',$id,document('Fact2FRF_Lookup.xml'))"/>
|
|
</xsl:function>
|
|
|
|
</xsl:stylesheet>
|