Releases for everyone!

Volume 6, Issue 5; 02 Jul 2022

You get a release! You get a release! You get a release! Everyone gets a release!

So. At XML Prague this year, the XProc Community Group decided to declare victory. We’ve had some last calls out there for a while, but there haven’t been any new issues raised recently. While my implementation has languished a bit, Achim’s MorganaXProc-III processor has been going along really well.

Yesterday, I released the “final” editorial draft of XProc 3.0: An XML Pipeline Language. Today, I had planned to do the final cleanup tasks on the standard step library, but I got, uh…distracted.

Editing the DocBook sources of the specifications reminded me that I needed to publish a “Candidate Release 2” of DocBook 5.2. We got a useful bug report on 5.2CR1 pretty quickly after its release (thank you!) but nothing new since. So I made the changes and packaged up a pull request for the TC to review.

That reminded me that I had an open bug on the DocBook xslTNG Stylesheets that needed looking into. Somehow, I published 1.7.0-x with Java 11 instead of Java 8. That wasn’t on purpose. It turns out the culprit was the configuration of the CircleCI machine. They retired the image I was using, so I had to upgrade and that got me a new version of Java.

(Insert a lost of hour fiddling with that!)

When I got that sorted out, I noticed a couple of other new, easy bugs so I fixed them as well.

While I was working on that, Martin Honnen reported that CoffeeSacksI’ve been quietly doing pretty regular releases of CoffeePot and its related Invisible XML APIs (CoffeeGrinder and CoffeeFilter). The day before yesterday, I published 1.99.9 which is starting to feel pretty close to “2.0”. (the Saxon extension functions for Invisible XML) threw an exception if he used Saxon 11 (or maybe it was Saxon 10, doesn’t matter).

It took a little while to track down, but the culprit is that I let the user pass an options map to the function. There’s an ugly API-level incompatibility between the way maps are handled in Saxon 10 and Saxon 11. (Mike changed an interface and that breaks binary compatibility: build it with Saxon 10, Saxon 11 will fail; build it with Saxon 11, Saxon 10 will fail.)

The last time this came up, in my Saxon extension functions for XInclude, I punted and shipped two versions of the library, one for Saxon 10 and one for Saxon 11. This had ugly knock-on effects like I had to publish two versions of the DocBook xslTNG Stylesheets.

I looked at CoffeeSacks and I thought, “no, I just don’t want to carry on forking things, there must be another way.” That lead to this delightful bit of code:

protected HashMap<String,String> parseMap(MapItem item) throws XPathException {
    HashMap<String,String> options = new HashMap<>();

    // The implementation of the keyValuePairs() method is
    // incompatible between Saxon 10 and Saxon 11. In order
    // to avoid having to publish two versions of this class,
    // we use reflection to work it out at runtime.
    // (Insert programmer barfing on his shoes emoji here.)
    try {
        Method keys = MapItem.class.getMethod("keys");
        Method get = MapItem.class.getMethod("get", AtomicValue.class);
        AtomicIterator aiter = (AtomicIterator) keys.invoke(item);
        AtomicValue next =;
        while (next != null) {
            AtomicValue value = (AtomicValue) get.invoke(item, next);
            options.put(next.getStringValue(), value.getStringValue());
            next =;
    } catch (NoSuchMethodException | IllegalAccessException
             | InvocationTargetException ex) {
        throw new IllegalArgumentException("Failed to resolve MapItem with reflection");

    return options;

(That IllegalArgumentException is never supposed to happen.)

I pushed another release of CoffeeSacks and went back to the DocBook stylesheets.

Except now I’ve been reminded that all the work I’ve been doing on the main branch also has to be cherry-picked over onto the main-10 branch because I have two releases to deal with because of the Saxon problem.

That makes me go back and look at sinclude again. Just how hard would it be to fix this, given that I’ve now worked out how to deal with the mapping issue?

Well, the XInclude function is doing more than just manage a map. It’s also loading documents, and to do that it uses the Saxon infrastructure for resolving URIs. That’s also totally different between Saxon 10 and Saxon 11. (That one’s on me, I integratedSpeaking of the XML Resolver, I released Java version 4.4.0 and C# version 1.4.0 last week. I added a feature to unceremoniously replace “\” characters in system identifiers with “/” characters on Windows. Because reasons. XML Resolver into Saxon 11.)


Just how hard would it be to fix this?

The way the resolver is accessed is different and there’s been a change to the characters method on the Receiver, but it’s not that much code…

So I dug in, fixed that, and released Saxon XInclude 4.1.0 which works equally well with Saxon 10 and Saxon 11. (It probably works with earlier Saxon releases as well, but I haven’t tested it.)

That meant I could release DocBook xslTNG Stylesheets version 1.7.1 without having to release different versions for Saxon 10 and Saxon 11.

And that simplifies a lot of things, because it means that all of the projects that use DocBook, including the XProc 3.0 standard step library, no longer have a weird dependency linkage between the version of SInclude, the version of xslTNG, and the version of Saxon.

And then I decided it was wine-o’clock and the standard step library could wait until tomorrow.

To recap:

  • XML Resolver 4.4.0
  • XML Resolver CS 1.4.0
  • CoffeeGrinder, CoffeeFilter, CoffeePot, and CoffeePress 1.99.9
  • CoffeeSacks 1.99.10
  • SInclude 4.1.0
  • DocBook xslTNG 1.7.1
  • XProc 3.0: An XML Pipeline Library (“final”)

It seems likely that I’ll get the XProc standard step library done tomorrow, but, you know, I get distracted sometimes.