When and how are xs:anyURI references made absolute?

It started with a bug report. Consider these pipelines:

In /some/path/lib.xpl:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:s="http://example.com/ns/steps"
                name="main" version="3.1" type="s:nop"
                exclude-inline-prefixes="s">
  <p:output port="result"/>
  <p:option name="file" as="xs:anyURI"/>

  <p:load>
    <p:with-option name="href" select="$file"/>
  </p:load>

</p:declare-step>

And in /some/path/pipe.xpl:

<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
                xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:s="http://example.com/ns/steps"
                name="main" version="3.1"
                exclude-inline-prefixes="s">
  <p:import href="lib/lib.xpl"/>
  <p:output port="result"/>

  <s:nop file="pipe.xpl"/> 
</p:declare-step>

What happens if you run pipe.xpl?

Well, today, in XML Calabash and MorganaXProc-III, you get an error:
file not found, /some/path/lib/pipe.xpl.

What happens is pipe.xpl gets passed to the step that implements s:nop as a relative URI and that relative URI gets resolved against the base URI of the p:with-option element in lib.xpl.

George Bina reported that as a bug (initially in email) and I created an issue.

   https://codeberg.org/xmlcalabash/xmlcalabash3/issues/105

Then I immediately had reservations about fixing it. The only practical fix is to say that pipe.xpl will be resolved against the base URI of <s:nop> “immediately”, that is to say, before it gets passed to the implementation of s:nop as an option.

That would make it impossible to pass a relative URI reference to a step in any option with the type xs:anyURI.

George then diligently, patiently, and persuasively laid out why it *is* a bug, and what the specifications actually *say* is that the base URI has to be resolved against <s:nop> as he describes.

I could try to argue that the spec authors didn’t *mean* that, but I can’t argue that it isn’t what the spec *says*.

It turns out there are no tests that rely on this behavior, so the change causes no failures in the test suite. (I’ll add a test for this case.)

There is a very small chance that this will break someone’s existing pipeline. If you have a step with an option that’s declared as xs:anyURI and you rely on passing a relative URI reference to it, and resolving that reference “early” will result in a different URI, you will get different behavior. That’s not ideal, but I also think it’s pretty unlikely.

I’ve persuaded myself that:

1. There are probably very few actual pipelines that rely on the current behavior.

2. Without this change, what a user has to write to get the URI resolved correctly against <s:nop> is:

  <s:nop file="{resolve-uri('pipe.xpl')}"/> 

which is pretty ugly for what should be a simple case.

3. With this change, if you want to be able to pass a relative URI to a step, simply make the option an xs:string instead of an xs:anyURI. Strings and URIs are pretty much interchangable so it’s not going to introduce any complications to the pipeline.

So I’m going to make the change. And I think Achim will as well.

                                        Be seeing you,
                                          norm

P.S. When I started writing this message, I think I had in mind that it would be a call for opinions. But in reviewing George’s comments and *what the spec* actually says:

   If a relative URI appears in an option of type xs:anyURI, the
   base URI against which it must be made absolute is the base URI
   of the p:option element. If the option value is specified using
   a syntactic shortcut, the base URI of the step element on which
   the shortcut attribute appears must be used.

I don’t think there’s anything to say here except: fair warning, I’m going to fix a bug. :-)

--
Norm Tovey-Walsh <ndw@nwalsh.com>
https://norm.tovey-walsh.com/

> Thou shalt not pray to Zeus for things your usual god would laugh at.

Received on Thursday, 26 June 2025 07:26:53 UTC