semantifyit / RocketRML

https://semantify.it
Creative Commons Attribution Share Alike 4.0 International
25 stars 12 forks source link

JSON array values get turned into strings #32

Closed adlerfaulkner closed 2 years ago

adlerfaulkner commented 2 years ago

When performing a mapping that references a key with an array value, the array gets transformed into a string instead of multiple triples.

Example With input json that has an array value such as:

{
  "name":"Tom A.",
  "favorite-numbers": [ 3, 33, 13 ]
}

And a mapping such as:

@prefix rr: <http://www.w3.org/ns/r2rml#> .
@prefix rml: <http://semweb.mmlab.be/ns/rml#> .
@prefix schema: <http://schema.org/> .
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .
@base <http://sti2.at/> . #the base for the classes

<#LOGICALSOURCE>
rml:source "./tests/arrayValueMapping/input.json";
rml:referenceFormulation ql:JSONPath;
rml:iterator "$".

<#Mapping>
  rml:logicalSource <#LOGICALSOURCE>;

   rr:subjectMap [
      rr:termType rr:BlankNode;
      rr:class schema:Person;
   ];

  rr:predicateObjectMap [
      rr:predicateMap [ rr:constant "http://example.com/favorite-numbers" ];
      rr:objectMap [
        rml:reference "favorite-numbers" ;
        rr:datatype "http://www.w3.org/2001/XMLSchema#integer" ;
      ];
  ] .

I am getting a response of:

{
  '@type': 'http://schema.org/Person',
  'http://example.com/favorite-numbers': {
    '@value': '3,33,13',
    '@type': 'http://www.w3.org/2001/XMLSchema#integer'
  },
  '@id': '_:http%3A%2F%2Fsti2.at%2F%23Mapping_1'
}

I would expect to get:

{
  '@type': 'http://schema.org/Person',
  'http://example.com/favorite-numbers': [
    {
      '@value': '3',
      '@type': 'http://www.w3.org/2001/XMLSchema#integer'
    },
    {
      '@type': 'http://www.w3.org/2001/XMLSchema#integer',
      '@value': '33'
    },
    {
      '@type': 'http://www.w3.org/2001/XMLSchema#integer',
      '@value': '13'
    }
  ],
  '@id': '_:http%3A%2F%2Fsti2.at%2F%23Mapping_1'
}
ThibaultGerrier commented 2 years ago

Hi again:)

For

{
  "foo": [1,2,3]
}

There is a difference in the json path $.foo and $.foo.*. One returns with a collection containing the array ([[1,2,3]]) and the other with a collection containing the elements of the array ([1,2,3]). Until now we created new triples for each element of the json path collection result and not for elements inside arrays inside the collection.

So in your example it is already possible to create multiple triples at the moment: rml:reference "favorite-numbers.*" ;

But it seems like the java mapper would also create multiple triples for your example. From some quick tests with it (the java mapper) it seems to me that if the json path collection result is a single array it will instead create triples for each element of that array. So I think it's fine if we support that as well :thumbsup:

adlerfaulkner commented 2 years ago

Ah I see, yes I could just change it to use rml:reference "favorite-numbers.*".

Yes, I also ran the same mapping with the java mapper so that's what I was basing my expectations off of. I wouldn't think there would be many cases of developers wanting their JSON arrays turned into comma separated strings instead of into a triple per element.

ThibaultGerrier commented 2 years ago

Yes, the .toString should probably do JSON.stringify for objects/arrays instead, otherwise you'd be getting [object Object] in the final data (which currently happens). the java mapper seems to do some java-json serialization that doesn't make too much sense, where {"a": 1} is transformed to "{a=1}" in the jsonld (which is of course better than [object Object], but it should probably be a JSON string instead)

ThibaultGerrier commented 2 years ago

Published #33 with v1.14.1.