Thank you Dimitre. I see that I didn't give you enough info.
Your solution is close but I get
<lineGroup type="stanza"/>
when blankLine does not precede a lineGroup.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kLGroup" match="lineGroup"
use="generate-id(preceding-sibling::blankLine[1])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="blankLine">
<lineGroup type="stanza">
<xsl:copy-of select="key('kLGroup', generate-id())"/>
</lineGroup>
</xsl:template>
<xsl:template match="lineGroup"/>
</xsl:stylesheet>
but source.xml can be more complicated with blankLine not preceding
lineGroup:
<text>
<blankLine/>
<lineGroup>
<line> </line>
<line> </line>
</lineGroup>
<lineGroup>
<line> </line>
<line> </line>
<lineGroup>
<line> </line>
<line> </line>
</lineGroup>
<line> </line>
</lineGroup>
<p/>
<blankLine/>
<p>This also happens. But does not produce a stanza.</p>
<p/>
<p/>
<p/>
<lineGroup>
<line>Make sure there is no stanza here</line>
<line> </line>
<lineGroup>
<line> </line>
<line> </line>
</lineGroup>
<line> </line>
</lineGroup>
<p/>
<blankLine/>
<lineGroup>
<line> </line>
<line> </line>
</lineGroup>
<lineGroup>
<line> </line>
<line> </line>
<lineGroup>
<line> </line>
<line> </line>
</lineGroup>
<line> </line>
</lineGroup>
<p/>
</text>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list