Project

Profile

Help

RE: Iter Versus Call Template; Byte-Code performance & Me... ยป functions.xsl

David Rudel, 2013-12-30 19:43

 
<?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 '&#09;'"/>
<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 '&#09;'"/>
</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>
    (1-1/1)