Your a element has 4 direct b children. The third one is
<b>
<c>
<b>b3.1</b>
</c>
</b>
You are processing the direct children by outputting their string-value (using xsl:value-of). The string value of the above element is "b3.1" (with some surrounding whitespace, unless you are using MSXML which incorrectly removes it).
I don't know what rules you want to apply. If you want to completely exclude b elements that have element children of their own, write an extra template rule
<xsl:template match="b[*]"/>
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference