At Debbie's instigation, I've been giving this some thought and trying to work back to first principles. We should probably be consistent with the way that the HTML5 specification attempts to resolve the problem, by modifying the semantics of XPath 1.0 and XSLT 1.0 as described here:
https://html.spec.whatwg.org/multipage/infrastructure.html#interactions-with-xpath-and-xslt
There are two parts to this.
Firstly, no-namespace names in path expressions are taken, under some circumstances, to match elements in the XHTML namespace. The specific circumstance is that the context node for the expression is "from an HTML DOM". This phrase is a bit too informal for our purposes; in an XSLT context it raises question like, if you do an xsl:copy-of a subtree from the HTML page, does that operate like an HTML DOM for this purpose? One way of interpreting the rule might be: for any axis step where the principal node kind is element and the node test is in the form of an NCName, if the context item for that axis step is an element in the XHTML namespace, or a document node whose child element is an element in the XHTML namespace, then interpret the name test as matching names in the XHTML namespace.
Secondly, tree construction. The HTML5 spec says that if the output method is "html", then: If the transformation program outputs an element in no namespace, the processor must, prior to constructing the corresponding DOM element node, change the namespace of the element to the HTML namespace, ASCII-lowercase the element's local name, and ASCII-lowercase the names of any non-namespaced attributes on the element.
Tying this to the output method doesn't work very well, at least not for XSLT 2.0+ where we have temporary trees and secondary result documents. The right time to do this conversion seems to be when we inject nodes into the HTML page. I think it's unambiguous when we are doing that, because it is only done using recognizable calls on xsl;result-document (plus things like ixsl:set-attribute)
Note that apart from these changes, elements in the HTML5 DOM appear as being in the XHTML namespace, for example namespace-uri() returns the XHTML namespace, and searches that explicitly request elements in the XHTML namespace succeed.
I have wondered about a more general solution to the problem of unprefixed element names in path expressions, which has always been one of the biggest usability problems in XPath. One solution is to interpret an unprefixed element name as matching on the local name only (that is, matching any namespace) -- and relying on the syntax Q{}local to match no namespace, where that is needed. Of course this would be a big incompatibility, so it would have to be switchable, but I suspect that it wouldn't break very much code, because the number of cases is very small where you write /a/b/c
and actually want to get no match on elements having the right local name but the wrong namespace. Another approach is a generalisation of the HTML5 modification to XPath semantics: a mode of operation in which an unprefixed NCName in an axis step means "match elements having the same namespace as the context node" (or the root element, if starting at a document node).
Whatever we do it's probably sufficiently disruptive that we should only consider it for JS2.