I would go with a pipe-line design. In the first stage, for a given document, collect all the @lb counts, with something like so...
<xsl:variable name="phase-1-output">
<xsl:apply-templates select="..some-expression.../@file" mode="phase-1">
</xsl:variable>
<template match="@file" mode="phase-1">
<xsl:apply-templates select="document(.)/testResults/sample" mode="phase-1" />
</template>
<xsl:template match="*" mode="phase-1" />
<xsl:template match="testResults/*[not(@lb = preceding::*/@lb)]" mode="phase-1" >
<lb-group key="{@lb}">
<xsl:number count="../*[@lb = current()/@lb]" />
<lb-group>
</xsl:variable>
This gives us a variable ($phase-1-output) which contains a list of elements (lb-group) containing a count and a key.Replace the select expression in the first template with what-ever you need for your problem space.
You may have @lb values which are shared across documents, and I presume that you want these grouped together and summed. So in phase 2, you apply the same grouping and counting technique as you did in phase 1, except that the input comes from the $phase-1-output variable, and you will be summing, instead of counting. To access the lb-groups within $phase-1-output, you will need to use the node-set() function.
Let me know if this is enough, or you want a full style-sheet.
Update
The OP has asked for a full style-sheet so here it is. Due to the lack of supplied appropriate sample data, I made up a couple of sample input documents with the same salient features as the OP provided one, but cut down and simplified as is appropriate for a Q & A site.
Input
Suppose we have 2 input files. The first file, with URL in1.xml has this content:
<testResults category="citrus">
<sample lb="lemon" />
<sample lb="lemon" />
<sample lb="green apple" />
<sample lb="green apple" />
<sample lb="green apple" />
</testResults>
And another file, with URL in2.xml has this content:
<testResults category="green food">
<sample lb="green apple" />
<sample lb="celery soup" />
<sample lb="peas" />
<sample lb="peas" />
</testResults>
The OP's stated requirement is to ...
count child elements of testResults grouping by lb attribute
Required output
Thus the required output will be as follows. I invented the non-informational structure because the OP forgot to supply it.
<root>
<lb-group lb-key="lemon">2</lb-group>
<lb-group lb-key="green apple">4</lb-group>
<lb-group lb-key="celery soup">1</lb-group>
<lb-group lb-key="peas">2</lb-group>
</root>
The reader will notice that there are 4 green apples. 3 are from the first input document, and 1 is from the second. I have assumed that the OP wanted counting across file boundaries. If separation is required, that is to say, counting on a strictly per-file basis, please let me know.
The solution
On the Saxon XSLT processor, in backwards compatibility mode, this result can be achieved by the following XSLT 1.0 style-sheet, which implements the aforementioned pipe-line design.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:so="http://stackoverflow.com/questions/11847434"
xmlns:exslt="http://exslt.org/common"
exclude-result-prefixes="xsl so exslt">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:variable name="test-result-files">
<so:file file="in1.xml" />
<so:file file="in2.xml" />
</xsl:variable>
<xsl:template match="/" >
<root>
<xsl:variable name="phase-1-output" >
<xsl:apply-templates select="document('')/*/xsl:variable
[@name='test-result-files']/so:file/@file" mode="phase-1" />
</xsl:variable>
<xsl:apply-templates select="$phase-1-output/lb-group" mode="phase-2" />
</root>
</xsl:template>
<xsl:template match="@file" mode="phase-1">
<xsl:apply-templates select="document(.)/testResults/sample" mode="phase-1" />
</xsl:template>
<xsl:template match="*" mode="phase-1" />
<xsl:template match="testResults/*[not(@lb = following::*/@lb)]" mode="phase-1" >
<xsl:variable name="lb-key" select="@lb" />
<lb-group lb-key="{$lb-key}">
<xsl:number count="*[@lb = $lb-key]" />
</lb-group>
</xsl:template>
<xsl:template match="*" mode="phase-2" />
<xsl:template match="lb-group[not(@lb-key = following::*/@lb-key)]" mode="phase-2">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:value-of select="sum(../*[@lb-key=current()/@lb-key])" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Caveat
Depending on what your XSLT engine is, you may have to replace the line...
<xsl:apply-templates select="$phase-1-output/lb-group" mode="phase-2" />
...with...
<xsl:apply-templates select="xslt:node-set($phase-1-output)/lb-group" mode="phase-2" />
...or the Microsoft equivalent, if using the MS processor.