I've had two mysteries come up recently using etree.parse() (lxml version 2.2.2).  Can anyone shed some light on how to work around these?

Start with this input
======input.html=========
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <h2 class="speechTitle">
            <p>Foo</p>
        </h2>
    </body>
</html>
======================

... then parse using ...

    htmlTree = etree.parse(open("input.html"), parser=etree.HTMLParser())
    open("out.xml", "wb").write(etree.tostring(htmlTree))

... the resulting XML is corrupted in two ways:

======output.html=========
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
    <body>
        <h2 class="speechTitle">
        </h2>
        <p>Foo</p>
    </body>
</html>
=======================

Problem 1:  The namespace declaration is duplicated (resulting in invalid XML)
Problem 2:  The <p> tag was moved outside of the <h2> tag.  Basic dom structure has been re-arranged.

Neither of these problems happen when I use the XMLParser (e.g. 'xmlTree = etree.parse(open("test2.html"), parser=etree.XMLParser())').  However I don't know if my source html will be valid XHTML or, more likely, just HTML.  Is there a way to get the HTMLParser to do the right thing?

Thanks for any suggestions or advice.