From 07f4f3954243e40975b97c9442cbede63eb96608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Lindstr=C3=B6m?= Date: Tue, 18 Nov 2025 17:28:11 +0100 Subject: [PATCH 1/5] Add test case 0028 Test use native types flag with non-native values. --- tests/fromRdf-manifest.jsonld | 10 ++++++++++ tests/fromRdf/0028-in.nq | 5 +++++ tests/fromRdf/0028-out.jsonld | 28 ++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 tests/fromRdf/0028-in.nq create mode 100644 tests/fromRdf/0028-out.jsonld diff --git a/tests/fromRdf-manifest.jsonld b/tests/fromRdf-manifest.jsonld index 787e4089..9e0bd705 100644 --- a/tests/fromRdf-manifest.jsonld +++ b/tests/fromRdf-manifest.jsonld @@ -205,6 +205,16 @@ }, "input": "fromRdf/0027-in.nq", "expect": "fromRdf/0027-out.jsonld" + }, { + "@id": "#t0028", + "@type": ["jld:PositiveEvaluationTest", "jld:FromRDFTest"], + "name": "use native types flag with non-native values", + "purpose": "Ensure that useNativeTypes flag being true does not interfere with values that cannot be serialized into a native value.", + "option": { + "useNativeTypes": true + }, + "input": "fromRdf/0028-in.nq", + "expect": "fromRdf/0028-out.jsonld" }, { "@id": "#tdi01", "@type": [ "jld:PositiveEvaluationTest", "jld:FromRDFTest" ], diff --git a/tests/fromRdf/0028-in.nq b/tests/fromRdf/0028-in.nq new file mode 100644 index 00000000..8cdda3ea --- /dev/null +++ b/tests/fromRdf/0028-in.nq @@ -0,0 +1,5 @@ + "string" . + "hello"@en . + "No"^^ . + "AAA"^^ . + "{\"x\": 1}"^^ . diff --git a/tests/fromRdf/0028-out.jsonld b/tests/fromRdf/0028-out.jsonld new file mode 100644 index 00000000..a9bdab56 --- /dev/null +++ b/tests/fromRdf/0028-out.jsonld @@ -0,0 +1,28 @@ +[ + { + "@id": "http://example.com", + "http://example.com/property": [ + { + "@value": "AAA", + "@type": "http://www.w3.org/2001/XMLSchema#double" + }, + { + "@value": { + "x": 1 + }, + "@type": "@json" + }, + { + "@value": "No", + "@type": "http://www.w3.org/2001/XMLSchema#boolean" + }, + { + "@value": "string" + }, + { + "@language": "en", + "@value": "hello" + } + ] + } +] From 8c0c5cf7ebe01de817ab51545357e1f73d4c14da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Lindstr=C3=B6m?= Date: Sat, 6 Jun 2026 15:33:20 +0200 Subject: [PATCH 2/5] Order 0028 test output as in input, for clarity --- tests/fromRdf/0028-out.jsonld | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/fromRdf/0028-out.jsonld b/tests/fromRdf/0028-out.jsonld index a9bdab56..ba4db3f1 100644 --- a/tests/fromRdf/0028-out.jsonld +++ b/tests/fromRdf/0028-out.jsonld @@ -3,25 +3,25 @@ "@id": "http://example.com", "http://example.com/property": [ { - "@value": "AAA", - "@type": "http://www.w3.org/2001/XMLSchema#double" + "@value": "string" }, { - "@value": { - "x": 1 - }, - "@type": "@json" + "@language": "en", + "@value": "hello" }, { "@value": "No", "@type": "http://www.w3.org/2001/XMLSchema#boolean" }, { - "@value": "string" + "@value": "AAA", + "@type": "http://www.w3.org/2001/XMLSchema#double" }, { - "@language": "en", - "@value": "hello" + "@value": { + "x": 1 + }, + "@type": "@json" } ] } From 03cf472cec9f7c514199174b1df14ce8e47631ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Lindstr=C3=B6m?= Date: Sat, 6 Jun 2026 16:08:16 +0200 Subject: [PATCH 3/5] Fix incomplete literal conversion When useNativeTypes is true, the else clause was never reached even if a native type couldn't be used; leaving only plain strings where e.g. language-tagged string literals were the source. This is a slight refactoring of the RDF to Object Conversion algorithm, to address this issue, whilst keeping or improving the clarify of the algorithm. Fixes #670 --- index.html | 100 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/index.html b/index.html index 642a47d8..2452b00a 100644 --- a/index.html +++ b/index.html @@ -5418,7 +5418,28 @@

Algorithm

RDF literal:
  1. Initialize a new empty map result.
  2. -
  3. Initialize converted value to value.
  4. +
  5. + Initialize converted value to null. +
    + Candidate Correction 10 +

    + Let converted value be initially unset, and only + actively set if a native type can be used. Then group the + other cases in an else block, defaulting to use the lexical + form of value. Since type is set in the + final else clause (unless it equals xsd:string), + there is no need to set it in the clause for + useNativeTypes. +

    +

    + Previously, the else clause was never reached even if a + native type couldn't be used, leaving only plain strings + where e.g. language-tagged string literals were the source. + For more information, refer to + issue 670. +

    +
    +
  6. Initialize type to null
  7. If useNativeTypes is true
      @@ -5433,12 +5454,8 @@

      Algorithm

      of value equals xsd:boolean, set converted value to true if the lexical form - - of value matches "true" or "1", or false - if it matches "false" or "0". - - If it matches neither, - set type to xsd:boolean. + of value matches "true" or "1", or false + if it matches "false" or "0".
    1. Otherwise, if the datatype IRI of value equals xsd:integer or @@ -5458,46 +5475,47 @@

      Algorithm

      If the conversion is successful, set converted value to its result.
    2. -
    3. - Otherwise, set type to datatype IRI - of value. -
-
  • Otherwise, if processing mode is not `json-ld-1.0`, - and value is a JSON literal, - set converted value to the result of - turning the lexical value of value - into the JSON-LD internal representation, and set type to @json. - If the lexical value of value is not valid JSON according to - the JSON Grammar [[RFC8259]], - an invalid JSON literal - error has been detected and processing is aborted.
  • -
  • Otherwise, if the datatype IRI of value starts with `https://www.w3.org/ns/i18n#`, - and {{JsonLdOptions/rdfDirection}} is `i18n-datatype`: -
      +
    1. + If converted value is null, +
      1. Set converted value to the lexical form of value.
      2. -
      3. If the string prefix of the fragment identifier - of the datatype IRI up until the underscore (`"_"`) is not empty, - add an entry `@language` to result and set its value to that prefix. -
        As `@direction` may be used without `@language`, - it is possible, and legitimate, to create a datatype IRI - such as `http://w3.org/ns/i18n#_ltr`, which does not encode a language tag.
      4. -
      5. Add an entry `@direction` to result and set its value to the substring of the - fragment identifier following - the underscore (`"_"`).
      6. +
      7. If processing mode is not `json-ld-1.0`, + and value is a JSON literal, + set converted value to the result of + turning the lexical value of value + into the JSON-LD internal representation, and set type to @json. + If the lexical value of value is not valid JSON according to + the JSON Grammar [[RFC8259]], + an invalid JSON literal + error has been detected and processing is aborted.
      8. +
      9. Otherwise, if the datatype IRI of value starts with `https://www.w3.org/ns/i18n#`, + and {{JsonLdOptions/rdfDirection}} is `i18n-datatype`: +
          +
        1. If the string prefix of the fragment identifier + of the datatype IRI up until the underscore (`"_"`) is not empty, + add an entry `@language` to result and set its value to that prefix. +
          As `@direction` may be used without `@language`, + it is possible, and legitimate, to create a datatype IRI + such as `http://w3.org/ns/i18n#_ltr`, which does not encode a language tag.
        2. +
        3. Add an entry `@direction` to result and set its value to the substring of the + fragment identifier following + the underscore (`"_"`).
        4. +
        +
      10. +
      11. Otherwise, if value is a + language-tagged string + add an entry @language to result and set its value to the + language tag of value.
      12. +
      13. Otherwise, set type to the + datatype IRI + of value, unless it equals xsd:string which is ignored.
    2. -
    3. Otherwise, if value is a - language-tagged string - add an entry @language to result and set its value to the - language tag of value.
    4. -
    5. Otherwise, set type to the - datatype IRI - of value, unless it equals xsd:string which is ignored.
    6. Add an entry @value to result whose value is set to converted value.
    7. If type is not null, add an entry @type @@ -7034,6 +7052,10 @@

      Change log

      once and for all in this step, rather than in each iteration. For more information, refer to issue 633.
    8. +
    9. 2026-06-06: Fix unconditional skip of other clauses when + useNativeTypes is `true`, as + described in Candidate Correction 10. +
    10. From f028c25320c715670376d9e58f00538aba01955a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Lindstr=C3=B6m?= Date: Wed, 10 Jun 2026 18:14:26 +0200 Subject: [PATCH 4/5] Apply suggestion from @TallTed Co-authored-by: Ted Thibodeau Jr --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 2452b00a..d85df892 100644 --- a/index.html +++ b/index.html @@ -5434,7 +5434,7 @@

      Algorithm

      Previously, the else clause was never reached even if a native type couldn't be used, leaving only plain strings - where e.g. language-tagged string literals were the source. + where, e.g., language-tagged string literals were the source. For more information, refer to issue 670.

      From 0f0c9f6c666facfd898d3c6e8754ee0623b45a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niklas=20Lindstr=C3=B6m?= Date: Wed, 17 Jun 2026 18:38:26 +0200 Subject: [PATCH 5/5] Move candidate correction block to change log item --- index.html | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/index.html b/index.html index d85df892..318d2426 100644 --- a/index.html +++ b/index.html @@ -5420,25 +5420,6 @@

      Algorithm

    11. Initialize a new empty map result.
    12. Initialize converted value to null. -
      - Candidate Correction 10 -

      - Let converted value be initially unset, and only - actively set if a native type can be used. Then group the - other cases in an else block, defaulting to use the lexical - form of value. Since type is set in the - final else clause (unless it equals xsd:string), - there is no need to set it in the clause for - useNativeTypes. -

      -

      - Previously, the else clause was never reached even if a - native type couldn't be used, leaving only plain strings - where, e.g., language-tagged string literals were the source. - For more information, refer to - issue 670. -

      -
    13. Initialize type to null
    14. If useNativeTypes is true @@ -7052,9 +7033,22 @@

      Change log

      once and for all in this step, rather than in each iteration. For more information, refer to issue 633.
    15. -
    16. 2026-06-06: Fix unconditional skip of other clauses when - useNativeTypes is `true`, as - described in Candidate Correction 10. +
    17. + 2026-06-06: + Fix the + RDF to Object Conversion algorithm, + which unconditionally skipped else clauses when + useNativeTypes was `true`, even if a + native type couldn't be used. This resulted in plain strings where, e.g., + language-tagged string literals were the source. + Instead, let converted value be initially unset, and only + actively set if a native type can be used. Then group the other cases + in an else block, defaulting to use the lexical form of + value. Since type is set in the final else clause + (unless it equals xsd:string), there is no need to set it in + the clause for useNativeTypes. + For more information, refer to + issue 670.