Skip to content

Object key abbreviation in the presence of JSON numbers. #129

Open

Description

@afs

This is taken from a report on [email protected]

and I've investigated further and reduced it to simpler, complete examples.

This is an appearance issue only. The data is correct and round-trips as expected.

It appears that using JSON native numbers interacts with the choice of field name and
the way it abbreviates the property given the context. It needs there to be numbers in the object slots. Strings and URIs work OK.

Example

prefix ex: <http://example/> 

ex:subject 
           ex:Common       1 ;
           ex:Same          "A" ;
           ex:CommonAA     2 ;
           ex:SameBB      "B" ;
           .

gives

{
  "@id" : "ex:subject",
  "ex:Common" : 1,
  "Common:AA" : 2,
  "Same" : "A",
  "SameBB" : "B",
  "@context" : {
    "Common" : {
      "@id" : "http://example/Common",
      "@type" : "http://www.w3.org/2001/XMLSchema#integer"
    },
    "Same" : "http://example/Same",
    "CommonAA" : {
      "@id" : "http://example/CommonAA",
      "@type" : "http://www.w3.org/2001/XMLSchema#integer"
    },
    "SameBB" : "http://example/SameBB",
    "ex" : "http://example/"
  }
}

Note the "ex:Common" : 1 and "Common:AA" : 2
Example
No prefix:

<http://example/subject>
           <http://example/Common>       1 ;
           <http://example/CommonAA>     2 ;
           .

gives

{
  "@id" : "http://example/subject",
  "http://example/Common" : 1,
  "Common:AA" : 2,
  "@context" : {
    "Common" : {
      "@id" : "http://example/Common",
      "@type" : "http://www.w3.org/2001/XMLSchema#integer"
    },
    "CommonAA" : {
      "@id" : "http://example/CommonAA",
      "@type" : "http://www.w3.org/2001/XMLSchema#integer"
    }
  }
}

Setup

    JsonLdOptions opts = new JsonLdOptions(baseURI);
    opts.useNamespaces = true ;
    opts.setUseNativeTypes(true);
    opts.setCompactArrays(true);

These examples produced with

 rdfcat --out JSONLD D.ttl 

using Jena latest development, including jsonld-java 0.5.1. The report was for Jena using jsonld-java 0.5.0.

Activity

  1. ansell commented on Dec 7, 2014

    @ansell
    Member

    Thanks for the complete report, I will look at this when I get time.

  2. ansell commented on Dec 31, 2014

    @ansell
    Member

    Changing this from Bug to Enhancement given that all of the information is preserved on a round-trip and the keys are valid, but I will try to track it down in the implementation today.

    Initial suspicion is that something is being done before the prefix/namespace check to result in order dependent prefix matching/non-matching.

  3. ansell commented on Jan 4, 2015

    @ansell
    Member

    I tried to replicate this for Sesame but was unable to as the way Sesame is pushing in the useNativeTypes flag doesn't seem to trigger something in the core the same way as Jena is doing. I will look at how you are doing it in Jena to see what I may be missing.

  4. afs commented on Jan 5, 2015

    @afs
    ContributorAuthor

    @Ansel, thanks for looking at this. If there is a better/correct way to set up the conversion from RDF to JSON-LD that Jena should be doing, then please let us know. The algorithm, I think (it was a while ago), follows what Sesame did at the time but (a) the translation might be wrong and (b) Sesame may have changed.

    Here is a json-ld/core example created by imitating the actions Jena takes to prepare the graph for output. Sorry - not pretty - it's basically copying over each of the steps the Jena code makes in a debug run. The presence/absence of opts.setUseNativeTypes triggers the report.

        public static void main(String... argv) throws Exception {
            // Prefix... or not (issue still arises when no prefix given)
            Map<String, Object> ctx = new HashMap<>() ;
            //ctx.put("ex", "http://example/") ;
    
            // Properties used
            Map<String, Object> x1 = new HashMap<>() ;
            x1.put("@id", "http://example/Common") ;
            x1.put("@type", "http://www.w3.org/2001/XMLSchema#integer") ;
    
            Map<String, Object> x2 = new HashMap<>() ;
            x2.put("@id", "http://example/CommonAA") ;opts.setUseNativeTypes
            x2.put("@type", "http://www.w3.org/2001/XMLSchema#integer") ;
    
            ctx.put("Common", x1) ;
            ctx.put("CommonAA", x2) ;
    
            // JSON-LD Options for compacyt step.
            JsonLdOptions opts = new JsonLdOptions("http://base/");
            opts.useNamespaces = true ;
            //opts.setUseRdfType(true);
            opts.setUseNativeTypes(true);
            opts.setCompactArrays(true);
    
            // RDF data
            RDFDataset dataset = new RDFDataset() ;
            dataset.addQuad("http://example/subject", "http://example/Common", "1", "http://www.w3.org/2001/XMLSchema#integer", null, null) ;
            dataset.addQuad("http://example/subject", "http://example/CommonAA", "2", "http://www.w3.org/2001/XMLSchema#integer", null, null) ;
            Object obj = new JsonLdApi(opts).fromRDF(dataset);
            Map<String, Object> localCtx = new HashMap<>() ;
            localCtx.put("@context", ctx) ;
    
            obj = JsonLdProcessor.compact(obj, localCtx, opts) ;
    
            StringWriter sw = new StringWriter() ;
            JsonUtils.writePrettyPrint(sw, obj) ;
            sw.write("\n") ;
    
            String d = sw.toString() ;
            System.out.print(d) ;
        }
    
  5. afs commented on Jan 5, 2015

    @afs
    ContributorAuthor

    Trying to find the difference in behaviour: the output from JsonApi.fromRDF is different and that influence the compaction but it looks like the compaction is just reacting to the different input.

    When use Native Types : true

    Then the output of JsonLdApi.fromRDF is an list of one element:

    [{@id=http://example/subject, http://example/CommonAA=[{@value=2}]}]
    

    and when the compact is run, for Context.compactIri and iri = http://example/CommonAA
    {@value=2}
    and the code goes to 2.14 where the arguments to selectTerm are:

    [@set, @none] , @language , [@null, @none]
    

    selectTerm returns null and the code proceeds to 5.1, but then finds "http://example/Common" is a prefix of "http://example/CommonAA":

    5.1: termDefinition = {@type=http://www.w3.org/2001/XMLSchema#integer, @reverse=false, @id=http://example/CommonAA}
    5.1: termDefinition = {@type=http://www.w3.org/2001/XMLSchema#integer, @reverse=false, @id=http://example/Common}
    5.2: termDefinition = {@type=http://www.w3.org/2001/XMLSchema#integer, @reverse=false, @id=http://example/Common}
    

    compactIRI gets set and the result from (6) is "Common:AA"

    When use Native Types : false

    The fromRDF output is different:

    [{@id=http://example/subject, http://example/CommonAA=[{@value=2, @type=http://www.w3.org/2001/XMLSchema#integer}]}
    

    And at 2.14::

    [@set, @none] , @type , [http://www.w3.org/2001/XMLSchema#integer, @none]
    

    and result in "CommonAA"

    A possibility is that the value map for the triple http://example/CommonAA should have the @type= for native types.

  6. umbreak commented on Jun 7, 2018

    @umbreak
    Contributor

    I think that's the reason why, when having a triple in a Model as

    <http://example.com/some> <http://schema.org/birthYear> "1999"^^<http://www.w3.org/2001/XMLSchema#integer> .
    

    and a context as

    {
      "@context": {
        "xsd": "http://www.w3.org/2001/XMLSchema#",
        "birthYear": {
          "@id": "http://schema.org/birthYear",
          "@type": "xsd:integer"
        }
      }
    }

    when converting that Model to a Json-LD string output (using WriterDatasetRIOT) and using the option UseNativeTypes to true. The output will not replace the prefixMapping "http://schema.org/birthYear" by birthYear and it will be as:

    {
      "@context": {
        "xsd": "http://www.w3.org/2001/XMLSchema#",
        "birthYear": {
          "@id": "http://schema.org/birthYear",
          "@type": "xsd:integer"
        }
      },
       "http://schema.org/birthYear": 1999
    }

    Now, If in the context I remove the part "@type": "xsd:integer", the output will replace the prefixMapping:

    {
      "@context": {
        "xsd": "http://www.w3.org/2001/XMLSchema#",
        "birthYear": {
          "@id": "http://schema.org/birthYear"
        }
      },
       "birthYear": 1999
    }
  7. garpinc commented on Apr 12, 2021

    @garpinc

    Is this a duplicate then? #313

    Because I want that last thing but somehow i can't seem to get that... Can you? Or is what you are describing where jena works (i.e: WriterDatasetRIOT) and jsonld-java doesn't?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions