Re: question on p:directory-list and base-uri()

Hello,

I think I’ve worked out what’s going wrong and a simple fix. There are still some interesting wrinkles though.

Given this document and @select="//c:directory/c:directory":

<c:directory xmlns:c="http://www.w3.org/ns/xproc-step"
             xml:base="file:/tmp/y/"
             name="y">
   <c:file xml:base="file" name="file"/>
   <c:directory xml:base="z/" name="z">
      <c:file xml:base="file" name="file"/>
   </c:directory>
</c:directory>

My implementation uses the select expression to locate the relevant nodes. This one:

   <c:directory xml:base="z/" name="z">
      <c:file xml:base="file" name="file"/>
   </c:directory>

And then it constructs a document containing that node. It constructs an XML document. What’s the base URI of *that* document?

Well, the wrong answer is, the same as its root element. Because that gives you a document with the base URI “file:/tmp/y/z/” that has a root element with an xml:base attribute of “z/” and bad happens.

(If the root element doesn’t have an xml:base attribute, surely the 99% case in general, or it has an xml:base that’s an absolute URI, no problem arises.)

One way to resolve this would be to remove the xml:base attribute from the root element in this case. If we’d said that from the beginning of XProc 1.0, then users would just be living with it. But I think saying it now would be pretty hostile.

The only other option (that I can think of) is to change the base URI of the *document* so that when the xml:base attribute is applied, the right thing happens.

I spent a few minutes pondering all of the complexity involved in taking an absolute URI and a relative xml:base and working out how to manipulate the absolute URI so that it was what you’d need to start with to get back the original when you applied the xml:base. The simple case, and you always get the simple case from p:directory-list, is easy. But users can put arbitrary values in xml:base attributes.

What do you do to “file:/tmp/y/z/” to make it the “before URI” if the xml:base attribute is “./spoon/../../x/y/test/”?

And then it occurred to me that the base URI of the element’s *parent* is *necessarily* the right value. The actual base URI of the element in question was literally constructed by applying its xml:base attribute value to the parent’s base URI.

We’re left with the wrinkle that the base URI of the *XML document* is going to be different (is going to be the base URI of the selected element’s parent) from the base URI of the document element in this case.

I can imagine that might be a little surprising, but I think it’s justified in order to avoid producing utterly the wrong base URI on the document element.

I’ve constructed a few tests and I’ve just thought of one more that I should write.

                                        Be seeing you,
                                          norm

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

> To see the world in a grain of sand,/And a heaven in a wildflower,/Hold infinity in the palm of your hand/and eternity for an hour.--William Blake

Received on Wednesday, 26 February 2025 08:46:27 UTC