В версии 2.0 и выше вы можете выполнить
.//B except .//*[not(self::A)]//B
Но поскольку вы запрашиваете решение XSLT, а не чисто решение XPath, выборочный рекурсивный спуск для достижения соответствующих элементов B может работать лучше:
<xsl:template match="A" mode="aab">
<!-- When we find an A, go on to its children -->
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*" mode="aab">
<!-- When we find something that isn't an A, go no further -->
</xsl:template>
<xsl:template match="B" mode="aab">
<!-- This is one of the B elements we are interested in -->
</xsl:template>