Q:

XSLT "Move" sibling content into closed preceding-sibling

My input has some non-conforming markup that I would like to fix, e.g.
<ul>
  <li>
  </li>
  <p>This is the first bullet item</p>
  <li>
  </li>
  <p>This is the second bullet item</p>
</ul>
...
<ul>
  <li>I am fine. No need to monkey with me.</li>
<ul>

which should be
<ul>
  <li>This is the first bullet item</li>
  <li>This is the second bullet item</li>
</ul>
...
<ul>
  <li>I am fine. No need to monkey with me.</li>
<ul>

I know how to "unwrap" the p elements
<xsl:template match="p[parent::ul and preceding-sibling::li]">
    <!-- Don't wrap or copy. Just process content. -->
    <xsl:apply-templates/>
</xsl:template>

but I can't figure out how to have the content of the unwrapped ps appear within the lis in the output. Somehow, I'm guessing, I need to identify the empty lis, instead create a new li and then add the content of the following-sibling p. Something like
<xsl:template match="li[not(li) and not(normalize-space())]">
    <li>
        <!-- how do I get content of following-sibling p here?? -->
        <xsl:apply-templates/>
    </li>
</xsl:template>

But this (obviously) does not work. I'm stuck and cannot find a solution. Suggestions?

A:

Somehow, I'm guessing, I need to identify the empty lis, instead create a new li and then add the content of the following-sibling p.

This seems to be a good idea, so try this:
<xsl:template match="li[normalize-space(text())='']">
  <xsl:copy>
    <xsl:value-of select="following-sibling::p[1]/text()" />
  </xsl:copy>
</xsl:template>

This fills empty li elements with the text() of the following p element.  
To get rid of the p elements, (somewhat) invert the XPath expression and put it in an empty template:
<xsl:template match="p[normalize-space(preceding-sibling::li[1]/text())='']" />

Output then is:
<ul>
  <li>This is the first bullet item</li>
  <li>This is the second bullet item</li>
</ul>

