Firstly, you need to learn how to use match templates and xsl:apply-templates. By ignoring these facilities you are working with one hand tied behind your back.
Secondly, you need to understand that you are writing nodes to a tree, not tags to a text file. This kind of thing doesn't make sense: "then end the current table </table> and start a new <fieldset> ". That's not the kind of operation XSLT does. Instructions in XSLT write nodes, and you can't write half a node.
What you seem to be doing here is adjacency grouping - group a maximal sequence of elements having some common property into a wrapper element. The property in question is having (or not-having) a child element. That's easily done in XSLT 2.0 with group-adjacent:
<xsl:for-each-group select="*" group-adjacent="exists(*)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<table>
<xsl:apply-templates/>
</table>
</xsl:when>
<xsl:otherwise>
<fieldset>
<xsl:apply-templates/>
Doing the same thing in 1.0 is much more difficult.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference