jsonrdfjson-ld

JSON-LD value objects with native JSON types in @value


I am trying to represent a typed value (numeric in this case, but it is the same for boolean) in JSON-LD in such a way that would allow my JavaScript code to work with it easily. If I declare the value with explicit datatype the way JSON-LD 1.1 specification and all other examples suggest, I represent the actual literal as a JSON string:

{
  "@context": {
    "age": {
      "@id": "http://example.com/age",
      "@type": "http://www.w3.org/2001/XMLSchema#int"
    }
  },
  "age": "21"
}

I understand this is in line with the way RDF looks at literals - datatype and lexical form both as strings. However, it seems this loses the simplicity of native JSON types. If I want to use the value of age in a JavaScript application, I have to manually handle the conversion instead of relying on the JS engine to read the value as a number from JSON. Moreover, the JSON-LD 1.1 specification does not state the @value must be a string.

So, my question is: can I use native JSON types (number, boolean) in JSON-LD value objects. Are there any best practices w.r.t. JavaScript applications handling such data?


Solution

  • Indeed, you may use non-string values as property values, or via @value in value objects. Per the JSON-LD 1.1 specification:

    The value associated with the @value key MUST be either a string, a number, true, false or null. If the value associated with the @type key is @json, the value MAY be either an array or an object.

    It is however important to understand that, in addition to whether such encoding is permitted by the grammar, you should also be aware of the specific conversion performed to obtain the lexical value, which, in this case, must be produced from the numeric value (since this could be non-trivial for fractional numbers). JSON-LD 1.1 Processing Algorithms and API tells us that:

    1. Otherwise, if value is a number with a non-zero fractional part (the result of a modulo‑1 operation) or an absolute value greater or equal to 1021, or value is a number and datatype equals xsd:double, convert value to a string in canonical lexical form of an xsd:double as defined in [XMLSCHEMA11-2] and described in § 8.6 Data Round Tripping. If datatype is null, set datatype to xsd:double.
    2. Otherwise, if value is a number, convert it to a string in canonical lexical form of an xsd:integer as defined in [XMLSCHEMA11-2] and described in § 8.6 Data Round Tripping. If datatype is null, set datatype to xsd:integer.

    Since your number is a reasonably-sized integer, it is treated as an xsd:integer for the relevant conversion, but xsd:int will be honored.

    Simply said ‒ if you specify an explicit datatype (other than xsd:double with an integer), the only thing that should change in how it is interpreted in RDF is the resulting datatype.