Library: URI handling (OMURI)
Import : omuri.xmd

Returns: relative form of absolute-uri

export string function
   relative      value string absolute-uri
            from value string base-uri


Use uri.relative to convert an absolute URI into a relative form with respect to another, base URI. This function performs the opposite operation from uri.extend, which converts a URI which is relative to another base URI into absolute form. For example, the result of

  uri.relative "ftp://ftp.omnimark.com/9.0/" from "ftp://ftp.omnimark.com/10.1/"
would be
  uri.relative "ftp://ftp.omnimark.com/10.1/" from "ftp://ftp.omnimark.com/10.1/"
would evaluate to

If absolute-uri cannot be made relative to base-uri because they refer to different schemes, uri.relative throws uri.cannot-be-made-relative. If absolute-uri is already in a relative form, it will be returned unmodified. The fragment portion of absolute-uri will be preserved in the result if present.


A common use of uri.relative is to transform all cross-references within a set of documents into relative form. This transformation allows moving the document set into a different root location without breaking the cross-references. The following program performs this task on all URIs specified in href attributes.

Note the two catch clauses for handling the exceptions. The uri.already-absolute exception indicates an href attribute that points to an outside resource, such as http://example.com/. These should not be modified. The uri.current-document-reference exception indicates that an attribute points to the file it is in. We can handle that case in different ways, but in this example we refer the attribute to the #head anchor.

  import "omuri.xmd"      prefixed by uri.
  import "omvfs.xmd"      prefixed by vfs.
  import "omxmlwrite.xmd" prefixed by xml.
  global string source-directory initial { "file:/origin/" }
  global string target-directory initial { "file:/destination/" }
  global string current-document
     local string documents variable
     vfs.list matching source-directory || "/*.xml" into documents
     repeat over documents as doc
        set current-document to uri.extend source-directory with doc
        using output as xml.writer into file uri.extend target-directory with doc
        do xml-parse scan file current-document
           output "%c"
  element #implied
     local markup-element-event new-element
     do when attribute "href" is specified
        local specified-attribute new-attributes variable
        copy specified attributes to new-attributes
           set new-attributes{"href"} to uri.relative new-attributes{"href"} from current-document
         catch uri.cannot-be-made-relative
        set new-element to create-element-event declaration of #current-markup-event attributes new-attributes
        set new-element to #current-markup-event
     signal throw #markup-start new-element
     output "%c"
     signal throw #markup-end   new-element

Related Topics
Other Library Functions