Skip to content

Converting RDF 1.2 data to RDF 1.1

Niklas Lindström edited this page Nov 10, 2024 · 4 revisions

Converting RDF 1.2 data to RDF 1.1(bis)

For use in an RDF 1.1-based system.

Triple terms

(See also https://github.com/w3c/rdf-semantics/issues/49 and https://github.com/w3c/rdf-star-wg/issues/114.)

"Unstarring" triple terms:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

DELETE {
  ?s ?rel <<( ?tts ?ttp ?tto )>> .
}
INSERT {
  ?s ?rel ?tt .
  ?tt a rdf:TripleTerm ;
    rdf:tripleTermSubject ?tts ;
    rdf:tripleTermPredicate ?ttp ;
    rdf:tripleTermObject ?tto .
}
WHERE {
  ?s ?rel <<( ?tts ?ttp ?tto )>> .
}

And conversely to "upgrade" again:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

DELETE {
  ?s ?rel ?tt .
  ?tt a rdf:TripleTerm ;
    rdf:tripleTermSubject ?tts ;
    rdf:tripleTermPredicate ?ttp ;
    rdf:tripleTermObject ?tto .
}
INSERT {
  ?s ?rel <<( ?tts ?ttp ?tto )>> .
}
WHERE {
  ?s ?rel ?tt .
  ?tt a rdf:TripleTerm ;
    rdf:tripleTermSubject ?tts ;
    rdf:tripleTermPredicate ?ttp ;
    rdf:tripleTermObject ?tto .
}

Literals with language and direction

(See Text-Direction-Proposal.)

I18N datatype variant

Converting literals with language and direction to datatyped literals:

DELETE {
  ?s ?p ?strlangdir .
}
INSERT {
  ?s ?p ?strdt .
}
WHERE {
  ?s ?p ?strlangdir .
  FILTER(hasLANG(?strlangdir) && hasLANGDIR(?strlangdir))
  BIND(LANG(?strlangdir) as ?lang)
  BIND(LANGDIR(?strlangdir) as ?langdir)
  BIND(STRDT(STR(?strlangdir),
             IRI(CONCAT("https://www.w3.org/ns/i18n/", ?lang, "--", ?langdir)))
       as ?strdt)
}

And back to literal with language and direction again:

DELETE {
  ?s ?p ?strdt .
}
INSERT {
  ?s ?p ?strlangdir .
}
WHERE {
  ?s ?p ?strdt .
  BIND(STR(DATATYPE(?strdt)) as ?dt)
  FILTER(STRSTARTS(?dt, "https://www.w3.org/ns/i18n/"))
  BIND(STRBEFORE(STRAFTER(?dt, "https://www.w3.org/ns/i18n/"), "--") as ?lang)
  BIND(STRAFTER(?dt, "--") as ?langdir)
  BIND(STRLANGDIR(STR(?strdt), ?lang, ?langdir) as ?strlangdir)
}

(This resorts to IRI inspection. Note that the I18N IRI is based on the non-normative JSON-LD 1.1 i18n namespace with one key difference: it ends with / instead of #. This is because the language tag space is a combinatory space of language tag and subtag for region, script, and various extensions, including transform (transliteraton) -t- and private use. If these IRIs were ever to resolve to provide information about the language, the payload would need to describe tens of thousands of entities, or references to descriptions that would have to be searched, since the protocol is HTTP and the fragment part would not be sent to the server.)

Literal as blank node variant

Converting literals with language and direction to "structured literals" as blank nodes:

DELETE {
  ?s ?p ?strlangdir .
}
INSERT {
  ?s ?p ?litnode .
  ?litnode a rdf:dirLangString ;  # alt. rdf:i18nString
    rdf:value ?lexical ;
    rdf:language ?lang ;
    rdf:direction ?langdir .
}
WHERE {
  ?s ?p ?strlangdir .
  FILTER(hasLANG(?strlangdir) && hasLANGDIR(?strlangdir))
  BIND(STR(?strlangdir) as ?lexical)
  BIND(LANG(?strlangdir) as ?lang)
  BIND(LANGDIR(?strlangdir) as ?langdir)
}

And back to literal with language and direction again:

DELETE {
  ?s ?p ?litnode .
  ?litnode a rdf:dirLangString ;
    rdf:language ?lang ;
    rdf:direction ?langdir .
}
INSERT {
  ?s ?p ?strlangdir .
}
WHERE {
  ?s ?p ?litnode .
  ?litnode a rdf:dirLangString ;
    rdf:language ?lang ;
    rdf:direction ?langdir .

  BIND(STRLANGDIR(STR(?lexical), ?lang, ?langdir) as ?strlangdir)
}
Clone this wiki locally