At the intersection of pain and suffering
There are Unix filesystems and Windows filesystems. There are Java URI objects and C# URI objects. There are file: URIs. And they all intersect in the XML Resolver.
For a long time, there was no standard for file: URIs and a number of
conventions arose. On Unix, filesystem access is pretty uniform and the mapping
is straightforward, but on Windows, there’s a lot more friction. First, Windows
uses “\” which isn’t allowed in a URI. Then it has drive letters which are
delimited by colons, as scheme names are in URIs. And finally, it has a UNC paths which begin with “\\” as distinct from “\”.
All of these have to get turned into file: URIs, one way or another. RFC 8089
attempts to document and untangle the various flavors of file: URI that exist
out there.
In Java, the predominant convention for UNC paths seems to be
file:////host/path. On .NET, they’re just file://host/path. Honestly, the
latter looks like it should be fine. But there’s also confusion sometimes about
how many slashes to put after file:. Sometimes you see file:///path which is
what you’d get if the host was empty, but Java seems to prefer file:/path,
leaving out the leading authority delimiter and the authority. (Both XProc and
QT4CG provide functions that attempt to resolve all this complexity for users.)
Unfortunately, somewhere in the intersection of Java and .NET and Unix and Windows, I got UNC paths wrong on .NET. As a knock-on effect, SaxonCS 13.0 gets them wrong too, because it relies on the XmlResolver.
I’ve fixed this in version 6.0.24, released a couple of days ago (for .NET only).
Thankfully, the .NET runtime works it all out in the URI class. There’s a
LocalPath field that contains a Windows-appropriate identifier.
(If the file doesn’t exist, or the scheme isn’t file:, it appears to
be the same as the AbsolutePath which is nice. So it wasn’t hard to fix after
it was reported.