0
votes

I would like to select and display specific rows. Let me first show you my xml file :

    <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="TestLogTest.xsl" type="text/xsl"?>
<TestLog>
    <TestLogItem id="0">
        <Message>Zero</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="1">
        <Message>One</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="2">
        <Message>Two</Message>
        <TypeDescription>Error</TypeDescription>
    </TestLogItem>
    <TestLogItem id="3">
        <Message>Three</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="4">
        <Message>******** TestCase PA-343 is finished *********</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="5">
        <Message>Five</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="6">
        <Message>Six</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
    <TestLogItem id="7">
        <Message>******** TestCase PA-450 is finished *********</Message>
        <TypeDescription>Normal</TypeDescription>
    </TestLogItem>
</TestLog>

Steps are part of TestCases, that means one TestCase contains several steps, but steps and TestCases are siblings. So first I have put an order in the xml file with this xsl file :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="k" match="TestLogItem[string(Message)]" use="following-sibling::TestLogItem[contains(Message, 'TestCase')][1]/@id"/>
    <xsl:template match="/TestLog">
        <table border="2">
            <th>Step</th> 
            <th>Test</th>
            <th>Result</th> 
            <xsl:for-each select="TestLogItem">
                <xsl:variable name="bingo" select="substring(Message, 19, 7)"/>
                <xsl:variable name="position" select="@id"/>
                <xsl:for-each select="key('k',@id)"> 
                    <tr>
                        <xsl:choose>
                            <xsl:when test="contains(TypeDescription, 'Error')">
                                <td bgcolor="#FF0000"><xsl:value-of select="@id"/></td>  
                                <td bgcolor="#FF0000"><xsl:value-of select="$bingo"/></td>
                                <td bgcolor="#FF0000"> Error </td>
                            </xsl:when>
                            <xsl:otherwise>
                                <td><xsl:value-of select="@id"/></td> 
                                <td><xsl:value-of select="$bingo"/></td>
                                <td> OK </td>
                            </xsl:otherwise>
                        </xsl:choose>
                    </tr>
                </xsl:for-each> 
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

Which gives me this xml :

<?xml version="1.0" encoding="UTF-8"?>
<table border="2">
   <th>Step</th>
   <th>Test</th>
   <th>Result</th>
   <tr>
      <td>0</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>1</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td bgcolor="#FF0000">2</td>
      <td bgcolor="#FF0000">PA-343</td>
      <td bgcolor="#FF0000">Error</td>
   </tr>
   <tr>
      <td>3</td>
      <td>PA-343</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>4</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>5</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
   <tr>
      <td>6</td>
      <td>PA-450</td>
      <td>OK</td>
   </tr>
</table>

Now I want to select only the last step of each TestCase (here steps 3 and 6) and display if there were an error or not like this :

<table>
 <tr>
  <td>PA-343</td>
  <td>Error</td>
 </tr>
 <tr>
  <td>PA-450</td>
  <td>OK</td>
 </tr>
</table>

But the problem is that I am using a xsl:for-each with the key and I don't know if I still have to work in the xsl:for-each node or if I have to think about a solution without the key.

Thank you for your answers

1

1 Answers

0
votes

If you only wanted to select the "last step" of each test-case, change the first xsl:for-each to include the condition that identifies such a step:

<xsl:for-each select="TestLogItem[contains(Message, 'TestCase')]">

Then, to check if any errors occurred for that step, don't have the inner xsl:for-each, instead use the key in the xsl:choose to check if any of the steps have the error

<xsl:when test="key('k',@id)[contains(TypeDescription, 'Error')]">

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="k" match="TestLogItem[string(Message)]" use="following-sibling::TestLogItem[contains(Message, 'TestCase')][1]/@id"/>
    <xsl:template match="/TestLog">
        <table border="2">
            <th>Step</th> 
            <th>Test</th>
            <th>Result</th> 
            <xsl:for-each select="TestLogItem[contains(Message, 'TestCase')]">
                <xsl:variable name="bingo" select="substring(Message, 19, 7)"/>
                <tr>
                    <xsl:choose>
                        <xsl:when test="key('k',@id)[contains(TypeDescription, 'Error')]">
                            <td bgcolor="#FF0000"><xsl:value-of select="$bingo"/></td>
                            <td bgcolor="#FF0000"> Error </td>
                        </xsl:when>
                        <xsl:otherwise>
                            <td><xsl:value-of select="$bingo"/></td>
                            <td> OK </td>
                        </xsl:otherwise>
                    </xsl:choose>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>