What is happening is that Saxon first attempts to see whether the module URI is known in particular whether there is a catalog that recognizes it. Because it is a relative reference, it is first resolved against the base URI (of the XSLT stylesheet), which results in a request for file://..../my-xslt.xslt#mymodule
. This succeeds in retrieving a resource (the stylesheet). There is no meaning attached to fragment identifiers in an XQuery resource, so the fragment identifier is ignored, and the stylesheet is retrieved. This is then parsed as XQuery, with the result
FOQM0003 The file imported for module null is not a valid XQuery library module. The
content starts: <xsl:stylesheet
Is Saxon's behaviour conformant? Well, the spec for load-query-module basically says that the strategy for locating a query module with the relevant module namespace is implementation-defined.
XQuery 4.12.1 says:
To maximize interoperability, query authors should use a string that is a valid absolute IRI.
Implementions must accept any string of Unicode characters. Target namespace URIs are compared using the Unicode codepoint collation rather than any concept of semantic equivalence.
Implementations may provide mechanisms allowing the target namespace URI to be used as input to a process that delivers the module as a resource, for example a catalog, module repository, or URI resolver. For interoperability, such mechanisms should not prevent the user from choosing an arbitrary URI for naming a module.
Similarly, implementations may perform syntactic transformations on the target namespace URI to obtain the names of related resources, for example to implement a convention relating the name or location of compiled code to the target namespace URI; but again, such mechanisms should not prevent the user from choosing an arbitrary target namespace URI.
As with other namespace URIs, it is common practice to use target namespace URIs whose scheme is "http" and whose authority part uses a DNS domain name under the control of the user.
So you're definitely inviting trouble by using a string that isn't a valid absolute URI. The spec says that we should accept any string of characters; but it doesn't say what we should do with it. The spec explicitly says that we may "provide mechanisms allowing the target namespace URI to be used as input to a process that delivers the module as a resource, for example a catalog..." which is what we are doing.
So I think the bottom line is that what you are doing is explicitly discouraged by the spec, and what we are doing is explicitly allowed by the spec.
Not a very satisfactory state of affairs, but things involving URIs very rarely are.