Home > Mobile >  Count() inside for-each
Count() inside for-each

Time:01-18

I'm not very familiar with xslt stylesheets and I need some help. In general the goal is to check how many occurrences of 'interface" are in set of 'testcases'. My idea was to iterate over include file interfaces_list.xml and each iteration use count function with contain to check how many occurrences of particular interface is present in extendedinfo's of all testcases. Probably problem is with the context, but I don't know how to temporary change it from 'interface' to 'testmodule'. I tried code as below but counted number is 0.

<xsl:variable name="interface_list" select="document('interface_list.xml')" />
            
<xsl:for-each select="$interface_list/header_xml/interface">
<xsl:variable name="nameofinterface"><xsl:value-of select="."/></xsl:variable>
    <tr>
    <td  width="60"><xsl:value-of select="count(//testcase/extendedinfo[contains(.,$nameofinterface)])"/></td>            
        </tr>               
</xsl:for-each>
here I want o count occurrences:            
<testmodule starttime="2022-07-27 16:29:54" timestamp="1397.491492" verdicts="2_basic" measurementid="ad20a6c0">
   <testgroup>
    <testcase starttime="2022-07-27 16:29:54" timestamp="1397.491492">      
          <extendedinfo type="text">[12345][654321][123654]</extendedinfo>
    </testcase>
    
    <testcase starttime="2022-07-27 16:30:18" timestamp="1421.291492">   
          <extendedinfo type="text">[12345]</extendedinfo>
    </testcase>
    
    <testcase starttime="2022-07-27 16:30:42" timestamp="1445.091492">
          <extendedinfo type="text">[654321]</extendedinfo>
    </testcase>
    
    <testcase starttime="2022-07-27 16:31:06" timestamp="1468.891492">
          <extendedinfo type="text">[123654]</extendedinfo>
    </testcase>
    </testgroup>
</testmodule>
file: interface_list.xml
<header_xml>

<interface>12345</interface>
<interface>654321</interface>
<interface>123654</interface>
<interface>112233</interface>

</header_xml>

CodePudding user response:

Assuming you are limited to XSLT 1.0 (with no extensions), you could do something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="interface_list" select="document('interface_list.xml')" />

<xsl:template match="/testmodule">
    <xsl:variable name="testmodule" select="." />
    <table>
        <xsl:for-each select="$interface_list/header_xml/interface">    
            <tr>
                <td>
                    <xsl:value-of select="."/>
                </td>
                <td>
                    <xsl:value-of select="count($testmodule/testgroup/testcase[contains(extendedinfo, current())])"/>
                </td>            
            </tr>               
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

to get:

Result

<?xml version="1.0" encoding="UTF-8"?>
<table>
  <tr>
    <td>12345</td>
    <td>2</td>
  </tr>
  <tr>
    <td>654321</td>
    <td>2</td>
  </tr>
  <tr>
    <td>123654</td>
    <td>2</td>
  </tr>
  <tr>
    <td>112233</td>
    <td>0</td>
  </tr>
</table>

Note that this assumes one interface value cannot be contained in another. If this assumption is incorrect (as I would suspect after noticing that they are not all of the same length), then change the counting instruction above to:

<xsl:value-of select="count($testmodule/testgroup/testcase[contains(extendedinfo, concat('[', current(), ']'))])"/>
  • Related