common-workflow-language / schema_salad

Semantic Annotations for Linked Avro Data

Home Page:https://www.commonwl.org/v1.2/SchemaSalad.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Differing URI resolution behavior for jsonldPredicate on purpose?

stmbaier opened this issue · comments

Description

If in a SALAD schema the jsonldPredicate of a SaladRecordField is set as

  • string, the provided URI is not resolved with respect to the provided base URI, instead the predicate URI is not pre-processed in any way
  • as object with property _id the provided URI is resolved with respect to the provided base URI during pre-processing.

Example

Input schema with directly provided URI string:

$base: "http://www.example.org/basketSchema"
$graph:
  - name: Basket
    type: record
    documentRoot: true
    fields:
      - name: basket
        type:
          type: array
          items: string
        jsonldPredicate: "#hasProducts"

Output JSON-LD Context:

{
    "@context": {
        "Basket": "http://www.example.org/basketSchema#Basket",
        "basket": "#hasProducts"
    }
}

Input schema with JsonldPredicate object:

$base: "http://www.example.org/basketSchema"
$graph:
  - name: Basket
    type: record
    documentRoot: true
    fields:
      - name: basket
        type:
          type: array
          items: string
        jsonldPredicate: 
          _id: "#hasProducts"

Output JSON-LD Context:

{
    "@context": {
        "Basket": "http://www.example.org/basketSchema#Basket",
        "basket": {
            "@id": "http://www.example.org/basketSchema#hasProducts"
        }
    }
}

Intuitively, I would have assumed that the two schemes would be equivalent, but apparently they are not.

Is this observed behavior correct (or a bug) and if so, where is this defined in the current SALAD specification (currently there is some documentation about jsonldPredicate pre-processing in 2.7 Record field annotations, but only for the cases, if the value is an object or @id)?

One could force link resolution by changing in the metaschema.yml the jsonldPredicate fiel definition for SchemaDefinedType and SaladRecordField from jsonldPredicate: "sld:jsonldPredicate" to

jsonldPredicate:
   _id: sld:jsonldPredicate
   _type: "@id"
   identity: false

Which seems a bit odd, if not a string, but an object is the value of jsonldPredicate field (but its working anyhow).

Or one could, during pre-processing normalize the jsonldPredicate field in a SaladRecordField to only contain JsonLdPredicate objects by transforming all strings to whole objects. Which seems nicer, and leads to a streamlined RDF representation that a sld:jsonldPredicate always has a blank node as object (rather than either the predicate IRI directly or a blank node, where the predicate IRI is found under the sld:_id predicate).

The jsonldPredicate: "#hasProducts" example is buggy. It should behave the same way as the second example. It has not been observed before because in practice when it is used that way, usually a full URL is provided.

One could force link resolution by changing in the metaschema.yml the jsonldPredicate fiel definition for SchemaDefinedType and SaladRecordField from jsonldPredicate: "sld:jsonldPredicate" to

jsonldPredicate:
   _id: sld:jsonldPredicate
   _type: "@id"
   identity: false

Which seems a bit odd, if not a string, but an object is the value of jsonldPredicate field (but its working anyhow).

Or one could, during pre-processing normalize the jsonldPredicate field in a SaladRecordField to only contain JsonLdPredicate objects by transforming all strings to whole objects. Which seems nicer, and leads to a streamlined RDF representation that a sld:jsonldPredicate always has a blank node as object (rather than either the predicate IRI directly or a blank node, where the predicate IRI is found under the sld:_id predicate).

The general form of this would be a directive in jsonldPredicate that specifies a field is pre-processed into a object, and the field value is assigned to a specific key of the object. Then this directive would be used to specify that a bare string gets turned into an object of { "_id": <value>}

The mapSubject/mapPredicate work somewhat like this but not exactly (they specify transformation of a set of key:value entries into a list objects), so it might require a new directive to be able to specify exactly the right behavior.