raphael icon indicating copy to clipboard operation
raphael copied to clipboard

Preserve local part of relative IRIs

Open dundalek opened this issue 6 months ago • 0 comments

Prefixed iris are stringified in shorthand form, which is useful when writing triples back to a file. However, relative iris resolved with base get absolutized, which loses that information.

(ns repro
  (:require
   [quoll.raphael.core :as raphael]
   [quoll.rdf :as rdf]))

(def triple
  (->> (raphael/parse "
@base <http://example.org/ns1/> .
@prefix : <http://example.org/ns2/> .
@prefix ex: <http://example.org/ns3/> .

<relative> :empty ex:prefixed.
")
       :triples
       first))

(mapv str triple)
; => ["<http://example.org/ns1/relative>" ":empty" "ex:prefixed"]

It would be nice if relative iris would work the same way with their shorthand form preserved. Instead of ["<http://example.org/ns1/relative>" ":empty" "ex:prefixed"] to stringify as ["<relative>" ":empty" "ex:prefixed"].

I think it would be possible to represent relative iris with nil prefix and a local part. Currently relative iri gets parsed as (rdf/iri "http://example.org/ns1/relative" nil nil), so instead they could be parsed it as (rdf/iri "http://example.org/ns1/relative" nil "relative").

The stringification part would need modification in Rudolf. In the current implementation the (str \: local) branch seems redundant, because when prefix is "", it is truthy, and will result in the same string.

 (toString [this]
   (if local
     (if prefix (str prefix \: local) (str \: local))
     (str \< iri \>)))

With a modified implementation is stringifies all iris in their shorthand form:

(defn toString-modified [{:keys [iri local prefix]}]
  (if local
    (if prefix (str prefix \: local) (str \< local \>))
    (str \< iri \>)))

(->> (into [(rdf/iri "http://example.org/ns1/relative" nil "relative")] (rest triple))
     (mapv toString-modified))
; => ["<relative>" ":empty" "ex:prefixed"]

What do you think?

dundalek avatar Jul 23 '25 17:07 dundalek