tags:

views:

23

answers:

1

I have written an xsl for converting the trx file of mstest into html.
Following from this link, I'm unable to get the class names and number of passes and failures for each class to be printed in the output.
I'm not sure where I'm goin wrong. the style sheet is applied on the same input file in the link.
Thanks.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" 
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
            xmlns:t="http://microsoft.com/schemas/VisualStudio/TeamTest/2006"&gt;
  <xsl:param name="today"></xsl:param>
  <xsl:param name="results"></xsl:param>
  <xsl:param name="pass" select="'Passed'"/>
  <xsl:param name="fail" select="'Failed'"/>
  <xsl:param name="incon" select="'Inconclusive'"/>
  <xsl:param name="error" select="'Error'"/>
  <xsl:key name="class-key" match="@className" use="."/>
  <xsl:variable name="unique-classes" select="//t:TestMethod/@className[generate-id(.)=generate-id(key('class-key',.))]" />

  <xsl:template match="/">

<html>
  <head>
    <script type="text/javascript">
       //Some javascript code
    </script>
  </head>
  <body style="font-family:Verdana; font-size:10pt">

    <a href="coverage.htm">Coverage Summary</a>
    <xsl:call-template name="summary" />
    <xsl:call-template name="details2" />
  </body>
</html>
</xsl:template>

 <xsl:template name="summary">
<h3>Test Summary</h3></code>
<table style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt">
  <tr>
    <td style="font-weight:bold;">Total</td>
    <td style="font-weight:bold;">Failed</td>
    <td style="font-weight:bold;">Passed</td>
    <td style="font-weight:bold;">Inconclusive</td>
    <td style="font-weight:bold;">Error</td>
  </tr>
  <tr>
    <td >
      <xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/@total"/>
    </td>
    <td style="background-color:pink;">
      <xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/@failed"/>
    </td>
    <td style="background-color:lightgreen;">
      <xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/@passed"/>
    </td>
    <td style="background-color:lightblue;">
      <xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/@inconclusive"/>
    </td>
    <td style="background-color:yellow;">
      <xsl:value-of select="/t:TestRun/t:ResultSummary/t:Counters/@error"/>
    </td>
  </tr>
</table>
</xsl:template>

<xsl:template name="details2">
<h3>Unit Test Results</h3>
<table border="0" style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt;">
  <tr>
    <td></td>
    <td id="data" style="font-weight:bold;">Test Name</td>
    <td id="data" style="font-weight:bold;">Result</td>
    <td id="data" style="font-weight:bold;">Duration</td>
  </tr>

  <xsl:for-each select="$unique-classes">
    <xsl:sort />
    <xsl:variable name="curClass" select="."/>

    <xsl:variable name="parentId" select="generate-id(./..)" />
    <xsl:variable name="currentId" select="generate-id(.)" />
    <tr id="{$parentId}">
      <td id="{$currentId}"
          style="font-weight:bold; cursor:pointer;"
          onClick="toggleDetail(this)">[+]</td>
        <xsl:sort select="@name"/>
        <xsl:variable name="testid" select="../@id"/>

          <xsl:with-param name="testid" select="."/>
          <xsl:with-param name="curClass" select="."/>

      <xsl:call-template name="groups" />
      </tr>
          <xsl:call-template name="classRunsDetail">
            <xsl:with-param name="curClass" select="."/>
          </xsl:call-template>

    <tr id="{$currentId}-end" style="display:none;">
      <td style="border-bottom:0px solid black;height:1px;background-color:black" colspan="4"></td>
    </tr>
  </xsl:for-each>
</table>
</xsl:template>

<xsl:template name="classRunsDetail">
  <xsl:param name="curClass"/>
  <xsl:variable name="parentId" select="generate-id(.)" />

<xsl:for-each select="//t:UnitTest/t:TestMethod[@className=$curClass]">
  <xsl:sort select="@name"/>

  <xsl:variable name="testid" select="../@id"/>
  <xsl:for-each select="//t:UnitTestResult[@testId=$testid]">
<tr id="{$parentId}">
  <xsl:attribute name="style">
    <xsl:choose>
      <xsl:when test="@outcome = $fail">background-color:pink;</xsl:when>
      <xsl:when test="@outcome = $pass">background-color:lightgreen;</xsl:when>
      <xsl:when test="@outcome = $incon">background-color:lightblue;</xsl:when>
      <xsl:otherwise>background-color:yellow;</xsl:otherwise>
    </xsl:choose>
    display:none;
  </xsl:attribute>
  <td></td>
  <td id="data">
    <xsl:value-of select="@testName"/>
  </td>
  <td id="data">
    <xsl:choose>
      <xsl:when test="@outcome = $fail">FAILED</xsl:when>
      <xsl:when test="@outcome = $pass">Passed</xsl:when>
      <xsl:when test="@outcome = $incon">Not Run</xsl:when>
      <xsl:otherwise>Error</xsl:otherwise>
    </xsl:choose>
  </td>
  <td id="data">
    <xsl:value-of select="@duration"/>
  </td>
</tr>
  </xsl:for-each>
</xsl:for-each>
</xsl:template>

<xsl:key name="class" match="t:TestMethod" use="@className"/>
<xsl:key name="result" match="t:UnitTestResult" use="@testName"/>

<xsl:template name="groups" match="t:TestMethod[count(.|key('class',@className)[1])=1]">
  <xsl:variable name="result" select="key('result',key('class',@className)/@name)"/>
    <td valign="bottom" style="background-color:beige;font-weight:bold;" colspan="3">
      <xsl:value-of select="@className"/>
    </td>
    <td>
      <xsl:value-of select="count($result[@outcome='Passed'])"/>
    </td>
    <td>
      <xsl:value-of select="count($result[@outcome='Failed'])"/>
    </td>
    <td>
      <xsl:value-of select="count($result[@outcome='Inconclusive'])"/>
    </td>
</xsl:template>

</xsl:stylesheet>
A: 

The provided stylesheet didn't even run...

I'm just guessing here, because there is no desired output.

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:t="http://microsoft.com/schemas/VisualStudio/TeamTest/2006"&gt;
    <xsl:param name="pass" select="'Passed'"/>
    <xsl:param name="fail" select="'Failed'"/>
    <xsl:param name="incon" select="'Inconclusive'"/>
    <xsl:param name="error" select="'Error'"/>

    <xsl:key name="class" match="t:TestMethod" use="@className"/>
    <xsl:key name="result" match="t:UnitTestResult" use="@testName"/>

    <xsl:template match="text()"/>

    <xsl:template match="/*">
        <html>
            <head>
                <script type="text/javascript">
                                    //Some javascript code
                </script>
            </head>
            <body style="font-family:Verdana; font-size:10pt">
                <a href="coverage.htm">Coverage Summary</a>
                <xsl:apply-templates select="t:ResultSummary|t:TestDefinitions"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="t:Counters">
        <h3>Test Summary</h3>
        <table style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt">
            <tr>
                <td style="font-weight:bold;">Total</td>
                <td style="font-weight:bold;">Failed</td>
                <td style="font-weight:bold;">Passed</td>
                <td style="font-weight:bold;">Inconclusive</td>
                <td style="font-weight:bold;">Error</td>
            </tr>
            <tr>
                <td >
                    <xsl:value-of select="@total"/>
                </td>
                <td style="background-color:pink;">
                    <xsl:value-of select="@failed"/>
                </td>
                <td style="background-color:lightgreen;">
                    <xsl:value-of select="@passed"/>
                </td>
                <td style="background-color:lightblue;">
                    <xsl:value-of select="@inconclusive"/>
                </td>
                <td style="background-color:yellow;">
                    <xsl:value-of select="@error"/>
                </td>
            </tr>
        </table>
    </xsl:template>

    <xsl:template match="t:TestDefinitions">
        <h3>Unit Test Results</h3>
        <table border="0" style="width:640;border:1px solid black;font-family:Verdana; font-size:10pt;">
            <tr>
                <td></td>
                <td id="data" style="font-weight:bold;">Test Name</td>
                <td id="data" style="font-weight:bold;">Result</td>
                <td id="data" style="font-weight:bold;">Duration</td>
            </tr>
            <xsl:apply-templates/>
        </table>
    </xsl:template>

    <xsl:template match="t:TestMethod[count(.|key('class',@className)[1])=1]">
        <xsl:variable name="result" select="key('result',key('class',@className)/@name)"/>
        <tr id="{generate-id(.)}">
            <td id="{generate-id(@className)}"
          style="font-weight:bold; cursor:pointer;"
          onClick="toggleDetail(this)">[+]</td>
            <td valign="bottom" style="background-color:beige;font-weight:bold;" colspan="3">
                <xsl:value-of select="@className"/>
            </td>
            <td>
                <xsl:value-of select="count($result[@outcome='Passed'])"/>
            </td>
            <td>
                <xsl:value-of select="count($result[@outcome='Failed'])"/>
            </td>
            <td>
                <xsl:value-of select="count($result[@outcome='Inconclusive'])"/>
            </td>
        </tr>
        <xsl:apply-templates select="$result">
            <xsl:sort select="@name"/>
            <xsl:with-param name="id" select="generate-id(@className)"/>
        </xsl:apply-templates>
        <tr id="{generate-id(.)}-end" style="display:none;">
            <td style="border-bottom:0px solid black;height:1px;background-color:black" colspan="4"></td>
        </tr>
    </xsl:template>

    <xsl:template match="t:UnitTestResult">
        <xsl:param name="id"/>
        <tr id="{$id}">
            <xsl:attribute name="style">
                <xsl:choose>
                    <xsl:when test="@outcome = $fail">background-color:pink;</xsl:when>
                    <xsl:when test="@outcome = $pass">background-color:lightgreen;</xsl:when>
                    <xsl:when test="@outcome = $incon">background-color:lightblue;</xsl:when>
                    <xsl:otherwise>background-color:yellow;</xsl:otherwise>
                </xsl:choose>
                <xsl:text>display:none;</xsl:text>
            </xsl:attribute>
            <td></td>
            <td id="data">
                <xsl:value-of select="@testName"/>
            </td>
            <td id="data">
                <xsl:choose>
                    <xsl:when test="@outcome = $fail">FAILED</xsl:when>
                    <xsl:when test="@outcome = $pass">Passed</xsl:when>
                    <xsl:when test="@outcome = $incon">Not Run</xsl:when>
                    <xsl:otherwise>Error</xsl:otherwise>
                </xsl:choose>
            </td>
            <td id="data">
                <xsl:value-of select="@duration"/>
            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet>

Note: I've reversed your logic. Don't drive the transformation with for-each instructions. Apply templates to descendants, instead.

Alejandro
That was just awesome. thank you so much Alejandro. By the way, could you please tell me why using for-each was causing the problem. I'd love to learn..
Sidd
@Sidd: I don't think `for-each` instructions were the problem, but they really obstructed maintenance. In declarative paradigms, you must know your input and output and then express their relationship. Also, this particular transformation could be called population: you already have a layout (XHTML) and you have to populate with data. You could put in some anchor (say @id) and when you find them during an "identity transformation" (look for it) you insert the data (multiple documents input with `document()` function). Take a look on this site: http://www.aranedabienesraices.com.ar
Alejandro