RMLio / RML-Mapper

Generate High Quality Linked Data from multiple originally (semi-)structured data (legacy)
http://RML.io
52 stars 20 forks source link

Error mapping content in JSON array #37

Closed canarvaeza closed 5 years ago

canarvaeza commented 6 years ago

Hi, The mapper was working fine but I just find this problem

I want to say a person isInvolved in 1 or more activities, in the input the "Activity" part is related with the Activity IDs:

{
  "Person": [
    {
      "Id": "xmlns.com/foaf/0.1/User/u001",
      "Role": {
        "Type": "User",
        "Value": "www.semanticweb.org/ontologies/domains/alzheimer#"
      },
      "Name": "Cristian",
      "Last-name": "Narvaez",
      "Device": {
        "Id": "www.w3.org/ns/sosa/iphone7/35-207306-844818-0"
      },
      "Activity": [
        {
          "Id": "www.semanticweb.org/ontologies/activity#activity/low/00001"
        },
        {
          "Id": "www.semanticweb.org/ontologies/activity#activity/low/00002"
        }
      ]
    }
  ],"Activity": [
    {
      "Id": "www.semanticweb.org/ontologies/activity#activity/low/00001",
      "Type": "www.semanticweb.org/ontologies/domains/alzheimer#Eat",
      "Time": {
        "Beginning": "2017-06-06T12:36:12Z",
        "Ending": "2017-06-06T12:38:12Z"
      },
      "Person": [
        {
          "Id": "xmlns.com/foaf/0.1/User/u001"
        },
        {
          "Id": "xmlns.com/foaf/0.1/User/u002"
        }
      ]
    },
    {
      "Id": "www.semanticweb.org/ontologies/activity#activity/low/00002",
      "Type": "www.semanticweb.org/ontologies/domains/alzheimer#Sit",
      "Time": {
        "Beginning": "2017-06-06T12:36:12Z"
      }
    }
  ]
}

This is the model

@prefix rr: <http://www.w3.org/ns/r2rml#>.
@prefix  rml: <http://semweb.mmlab.be/ns/rml#> .
@prefix crml:       <http://semweb.mmlab.be/ns/crml#> .
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .

## --------------- DEPENDENCIES ----------- ###

### ----- MCONTEXT ----- ###
@prefix mcontext: <http://www.semanticweb.org/ontologies/mcontext#>.
@prefix alzheimer: <http://www.semanticweb.org/ontologies/domains/alzheimer#>.

### ----- ROLE ------ ##
@prefix role: <http://www.semanticweb.org/ontologies/role#>.

### ------ PERSON ------ ###
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

### ----- ACTIVITY ----- ###
@prefix activity: <http://www.semanticweb.org/ontologies/activity#>.

## ------------------------------------------###

## --------------- MAPPINGS --------------- ##
### ------ PERSON ------ ###

<#PersonMapping>
    rml:logicalSource [
        rml:source "{direction}inputMin.json";
        rml:referenceFormulation ql:JSONPath;
        rml:iterator "$.Person.[*]"
    ];

    #define la uri en el sistema
    rr:subjectMap [
        rr:template "http://{Id}";
        rr:class foaf:Person
    ];

    ## ----- BASIC ATRIBUTES ----- ##

    rr:predicateObjectMap [
        rr:predicate foaf:firstname;
        rr:objectMap
        [
            rml:reference "Name"
        ]
    ];

    rr:predicateObjectMap [
        rr:predicate foaf:lastname;
        rr:objectMap
        [
            rml:reference "Last-name"
        ]
    ];

    ## ----- EXTERNAL ATRIBUTES ----- ##

    rr:predicateObjectMap [
        rr:predicate mcontext:hasRol;
        rr:objectMap
        [
            rr:parentTriplesMap <#RolMapping> ;
        ]
    ]**,[
        rr:predicate mcontext:isInvolvedIn;
        rr:objectMap
        [
            rr:template "http://{Activity.[*].Id}";
        ]
    ].**

### ------- ROL ------ ###

<#RolMapping>
    rml:logicalSource [
        rml:source "{direction}inputMin.json";
        rml:referenceFormulation ql:JSONPath;
        rml:iterator "$.Person.[*].Role"
    ];

    #define la uri en el sistema
    rr:subjectMap [
        rr:template "http://{Value}";
    ].

I expected this model to gave me something like

mcontext:isInvolvedIn <http://www.semanticweb.org/ontologies/activity#activity/low/00001>, <http://www.semanticweb.org/ontologies/activity#activity/low/00001> .

but the output I get is:

<http://xmlns.com/foaf/0.1/User/u001> a foaf:Person ;
    mcontext:hasRol <http://www.semanticweb.org/ontologies/domains/alzheimer#> ;
    foaf:firstname "Cristian" ;
    foaf:lastname "Narvaez" ;
    mcontext:isInvolvedIn <http://www.semanticweb.org/ontologies/activity#activity/low/00001> .

I tried different approaches and the interesting thing is that if you set a datatype


[
        rr:predicate mcontext:isInvolvedIn;
        rr:objectMap
        [
            rr:template "http://{Activity.[*].Id}";
            rr:datatype xsd:dateTime
        ]
    ].

It just put the two individuals

<http://xmlns.com/foaf/0.1/User/u001> a foaf:Person ;
    foaf:firstname "Cristian" ;
    foaf:lastname "Narvaez" ;
    mcontext:isInvolvedIn "http://www.semanticweb.org/ontologies/activity#activity/low/00001"^^<http://www.w3.org/2001/XMLSchema#dateTime> , "http://www.semanticweb.org/ontologies/activity#activity/low/00002"^^<http://www.w3.org/2001/XMLSchema#dateTime> ;
    mcontext:hasRol <http://www.semanticweb.org/ontologies/domains/alzheimer#> .

Any idea how to solve this?

pheyvaer commented 5 years ago

Hi,

We've updated the RMLMapper and it can now be found here. I've tried with your data and mapping and I get the expected triples. If you have still issues, you can open a new issue at the repo of the new RMLMapper.

Simo-climb commented 4 years ago

Hi @pheyvaer

I found this issue in looking for an example of using RML and YARRRML to map nested objects and arrays. This was one of the few examples around that I could find with nested objects.

I couldn't track down any specific mention of how to deal with nested levels of these in the relevant specs.

I take it from this use case that RML Mapper supports nested objects. Is there documentation or examples for this ?

Does YARRRML support deeply nested structures ? Any documentation links ?

I've tried to reconstruct the above person RML model using the matey YARRRML editor and RML generator but without an example I'm not getting far.

Do you have an example you could point me to please ?

A more trivial example would be the following with the aim of mapping the Street value to ex:StreetName "Smth"

{
    "persons": [
        {
            "firstname": "John",
            "lastname": "Doe",

        "Address": [
            { "Street": "Smith",
            "Suburb": "Bland"

            }
            ]
                },
        {
            "firstname": "Jane",
            "lastname": "Smith"
        },
        {
            "firstname": "Sarah",
            "lastname": "Bladinck"
        }
    ]
}

The closest I got to a mapping was only to the Address array with all values returned as the literal value using the following

prefixes:
  ex: "http://example.com/"

mappings:
  person:
    sources:
      - ['data.json~jsonpath', '$.persons[*]']
    s: http://example.com/$(firstname)
    po:
      - [a, foaf:Person]
      - [ex:name, $(firstname)]
      - [ex:Address, $(Address)]

Many thanks in advance

Simon

pheyvaer commented 4 years ago

Hi @Simo-climb

Could you move this to a new issue? Thanks!