XML Resolver refactor refactor
Working on the C# implementation of the XML Resolver was instructive. It instructed me that the new design was kind of a mess and the Java implementation of that design was also…bad. So I’ve fixed that.
As of sometime this afternoon, all of the unit tests for both the Java and C# versions of XML Resolver passed. That’s a big milestone; it paves the way for official “6.0.0” releases.
I’m working my way through the JavaDoc and then I’ll have to go through whatever the C# version of that is called. Then I have to turn my attention to the user documentation.
It’s awkward because a lot of things are the same, but a lot of things
are different. What I’ll probably end up doing is moving the current
documentation under a /legacy/
URI and making the main pages about
the new version.
The new version is a substantial improvement and I want to encourage folks to migrate. At the same time, it’s probably a bit of infrastructure in your project and I’ve done that annoying thing where I’ve changed the API, so I know it’s not something everyone will want to do immediately.
The biggest user-visible change, I think, is that a bunch of different
objects that implemented different APIs have all gone away. The
Resolver
, StAXResolver
, and XercesResolver
objects are no more.
Most of the APIs were implemented on Resolver
, but there were
several different resolver objects because the various systems have
incompatible APIs.
Instead, now there’s an XMLResolver
object that has methods that return
instances of the different APIs. That feels a lot cleaner. You can
also use the XMLResolver
object to interrogate the catalog
or resolve resources directly, if that’s a thing you want to do.
The design is more-or-less the same now in both Java and C#. I’ve worked harder to make the C# API more C#-like (using the naming conventions expected, for example, and treating nullable with care).
Where they diverge, I think it’s because there are fundamental differences in how the Java APIs and the C# API work. Aside from the thing that’s absolutely fucking broken on C#, those differences are a matter of design. I’d have made different choices, but no one asked me.
One slightly awkward thing on C# is that my object is called
XmlResolver
and the system API for setting up a resolver on C# is
called System.Xml.XmlResolver
. That means there’s a name clash. I’ve
noodled around with various ways to fix that, but I don’t really like
any of them.
This means that in C# you’re going to be left doing this:
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = XmlResolver.XmlResolver.GetXmlResolver();
Which is, on the one hand, kind of ugly. But on the other hand, that’s pretty much exactly the one line of code that you need, so I’m going to see if that’s ok.
Also up next: “integration testing”. That is, will it work on SaxonJ and SaxonCS? It probably won’t work in Saxon 12.x because of the API changes, so I’ll be focusing on V.next, the-thing-that-will-eventually-be-13.0.