The SPBModel data-structure lends itself well to querying and transforming with Xslt. Here is the Xslt code that is used by the Quick-Form online model to create the output "Confidence Interval Table".
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<!--- // Output an Html page with table displaying // confidence interval for requested frame --><xsl:output method="html" indent="yes"/>
<xsl:variable name="DesiredFrame" select="/SPBModel/Batch[1]/Frame[1]/FrameName"/>
<!-- // Save the result document as an *.htm or *.html file // then use your browser to view the table --><xsl:template match="/SPBModel">
<!--<xsl:variable name="FrameName">AL-COOSA1V1</xsl:variable>--><html>
<head>
<xsl:comment>
Save as *.htm or *.html file, then launch with browser
</xsl:comment>
<title>
<xsl:text>Confidence Interval Summary for </xsl:text>
<xsl:value-of select="$DesiredFrame"/>
</title>
</head>
<body>
<h1>
Confidence Interval Summary for <xsl:value-of select="$DesiredFrame"/>
</h1>
<table>
<tr>
<th>Sim Day</th>
<th>Inf Coef</th>
<th>Lower Inf</th>
<th>SharpHog Inf</th>
<th>Upper Inf</th>
<th>Dead Coef</th>
<th>Lower Dead</th>
<th>SharpHog Dead</th>
<th>Upper Dead</th>
</tr>
<xsl:apply-templates select="/SPBModel/Batch/Frame[FrameName = $DesiredFrame]/EngineOutput"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="EngineOutput">
<xsl:variable name="InfCoef">
<xsl:call-template name="InterpInf">
<xsl:with-param name="simday" select="SimulationDay"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="DeadCoef">
<xsl:call-template name="InterpDead">
<xsl:with-param name="simday" select="SimulationDay"/>
</xsl:call-template>
</xsl:variable>
<tr>
<td>
<xsl:value-of select="SimulationDay"/>
</td>
<td>
<xsl:value-of select="format-number($InfCoef, '0.000')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesInfested - TreesInfested * $InfCoef, '#')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesInfested, '#')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesInfested + TreesInfested * $InfCoef, '#')"/>
</td>
<td>
<xsl:value-of select="format-number($DeadCoef, '0.000')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesDead - TreesDead * $DeadCoef, '#')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesDead, '#')"/>
</td>
<td>
<xsl:value-of select="format-number(TreesDead + TreesDead * $DeadCoef, '#')"/>
</td>
</tr>
</xsl:template>
<!-- // Lookup-list of days into a simulation --><xsl:variable name="DayList">
<xsl:text>0.0, 1.0, 8.0, 15.0, 22.0, 29.0, 36.0, 43.0, 50.0, 57.0, 64.0, 71.0, 78.0, 85.0, 92.0, 92.3</xsl:text>
</xsl:variable>
<!-- // Lookup-list of infested confidence interval coefficients --><xsl:variable name="InfList">
<xsl:text>0.0, 0.022, 0.055, 0.080, 0.094, 0.120, 0.138, 0.173, 0.197, 0.208, 0.225, 0.250, 0.277, 0.299, 0.310, 0.311</xsl:text>
</xsl:variable>
<!-- // lookup-list of dead confidence interval coefficients --><xsl:variable name="DeadList">
<xsl:text>0.0, 0.003, 0.042, 0.058, 0.066, 0.071, 0.087, 0.107, 0.122, 0.133, 0.145, 0.162, 0.180, 0.200, 0.215, 0.216</xsl:text>
</xsl:variable>
<!-- // Get the Confidence Interval Coefficient of Dead Trees for this Simulation Day--><xsl:template name="InterpDead">
<xsl:param name="simday"/>
<xsl:call-template name="Interpolate">
<xsl:with-param name="day" select="$simday"/>
<xsl:with-param name="days">
<xsl:call-template name="CSVBranch">
<xsl:with-param name="list" select="$DayList"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="ratios">
<xsl:call-template name="CSVBranch">
<xsl:with-param name="list" select="$DeadList"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- // Get the Confidence Interval Coefficient of Infested Trees for this Simulation Day--><xsl:template name="InterpInf">
<xsl:param name="simday"/>
<xsl:call-template name="Interpolate">
<xsl:with-param name="day" select="$simday"/>
<xsl:with-param name="days">
<xsl:call-template name="CSVBranch">
<xsl:with-param name="list" select="$DayList"/>
</xsl:call-template>
</xsl:with-param>
<xsl:with-param name="ratios">
<xsl:call-template name="CSVBranch">
<xsl:with-param name="list" select="$InfList"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
<!-- // Interpolate Template --><xsl:template name="Interpolate">
<xsl:param name="day" />
<xsl:param name="days" />
<xsl:param name="ratios"/>
<!-- // Assuming the values are ordered lowest to highest, // get from original scale the last value lower than input. . .--><xsl:variable name="tmin" select="msxsl:node-set($days)/Value[.<=$day][last()]" />
<!-- // . . .and first value higher than input --><xsl:variable name="tmax" select="msxsl:node-set($days)/Value[.>$day][1]" />
<!-- // Find the index, or position in their list, of the min and max--><xsl:variable name="ind">
<xsl:for-each select="msxsl:node-set($days)/Value">
<xsl:if test=".=$tmin">
<xsl:value-of select="position()"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!-- // Get values with those indexes from result scale --><xsl:variable name="rateA" select="msxsl:node-set($ratios)/Value[position()=$ind]"/>
<xsl:variable name="rateB" select="msxsl:node-set($ratios)/Value[position()=$ind+1]"/>
<!-- // Return the rate if no interpolation needed, // or find a value between those provided by the list. --><xsl:choose>
<xsl:when test="$rateA = $rateB">
<xsl:value-of select="$rateA" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="(($day - $tmin) div ($tmax - $tmin)) * ($rateB - $rateA) + $rateA"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- // CSV Branch Template // Takes text list of comma-separated values // and return as element list --> <!-- // Elements in result are named Value, // with the result value as content --><xsl:template name="CSVBranch">
<xsl:param name="list"/>
<xsl:variable name="first" select="substring-before($list, ',')"/>
<xsl:variable name="rest" select="substring-after($list, ',')" />
<!-- // Doea list exist? From original call or from recursion --><xsl:if test="$list">
<xsl:choose>
<!-- // When the string list ws split by commas, // did it create a value for first? --><xsl:when test="$first">
<xsl:element name="Value">
<!-- // $first will be a single number string --><xsl:value-of select="normalize-space($first)"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Value">
<!-- // No first element means the list contains // only the last value to be added--><xsl:value-of select="normalize-space($list)"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
<!-- // Call this template recursively on any remaining values --><xsl:call-template name="CSVBranch">
<xsl:with-param name="list" select="normalize-space($rest)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
