zazuko / xrm

A friendly language for mappings to RDF
MIT License
1 stars 0 forks source link

Parent triple map support #31

Closed nicky508 closed 8 months ago

nicky508 commented 4 years ago

To make nested structures, parenttriple maps need to be added to the DSL, example:

ex:Object rdf:type class:Object ;
prop:lotSize [  schema:value 11050.07095540000;
            schema:unitCode 'FTK' ];
ktk commented 4 years ago

I see what you need but how would that look like in R2RML spec?

nicky508 commented 4 years ago

It would look like:

<#RmlMapping>  
        rr:subjectMap[
                  rr:class class:Object
                  rr:template  "http://data.example.com/{object}"
                ] ;

            rr:predicateObjectMap [
            rr:predicate prop:lotSize;
            rr:objectMap [
                   rr:parentTriplesMap <#lotSize>;
            ]
        ].

<#lotSize> 
                rr:subjectMap [
                       rr:termType rr:BlankNode
                ] ;

        rr:predicateObjectMap 
          [
            rr:predicate schema:unitCode
            rr:objectMap [
              rml:reference "unitCode";
            ]
          ];

                  rr:predicateObjectMap 
          [
            rr:predicate schema:value
            rr:objectMap [
              rml:reference "value";
            ]
          ];

The adjustment would be referencing to another mapping in the Xtext grammer and adding termTypes.

nicky508 commented 4 years ago

Added parent triple map support (without the blanknodes)

mchlrch commented 4 years ago

@nicky508 Is the implementation of this feature finished? What is missing and do we need what is missing?

Can you please put a sample of how it looks in the DSL?

Can it do the following example from the R2RML spec ?

<#DeptTriplesMap>
    rr:logicalTable [ rr:tableName "DEPT" ];
    rr:subjectMap [
        rr:template "department/{DEPTNO}";
        rr:class ex:Department;
    ];
    rr:predicateObjectMap [
        rr:predicate ex:location;
        rr:objectMap [ rr:parentTriplesMap <#SiteTriplesMap> ];
    ].

<#SiteTriplesMap>
    rr:logicalTable [ rr:tableName "DEPT" ];
    rr:subjectMap [
        rr:template "site/{LOC}";
        rr:class ex:Site;
    ];
    rr:predicateObjectMap [
        rr:predicate ex:siteName;
        rr:objectMap [ ex:column "LOC" ];
    ].
nicky508 commented 4 years ago

@mchlrch It is not complete implemented. I only implemented the basics. To make it complete we have to add rr:child and rr:parent as well. I tried to add them as well. But I was not able to get it work in the mapping so for that moment I implemented only the feature mostly used. Besides, I have not seen a lot of cases where these params are used (so, a bit of lacking knowledge how it actually works).

I am able to recreate the example above. I added the example to the mapping-examples (separate branch): https://github.com/zazuko/rdf-mapping-dsl-user/tree/issue31/mapping-examples/department-mapping

mchlrch commented 4 years ago

@nicky508 I integrated your changes with some minor modifications in https://github.com/zazuko/rdf-mapping-dsl/commit/ac09bb47cf765d440d7c77d710f41b17cc15ad1b

Sample DSL:

map DeptTriplesMap from Department {
    subject template "department/{0}" with DEPTNO;

    types ex.Department;

    properties
        ex.location parent-map SiteTriplesMap 
}

map SiteTriplesMap from Department {
    subject template "site/{0}" with LOC;

    types ex.Site;

    properties
        ex.siteName from LOC;
}

Sample R2RML output:

PREFIX rr: <http://www.w3.org/ns/r2rml#>
PREFIX ex: <http://example.org/>

<#DeptTriplesMap>
    rr:logicalTable [ rr:tableName "DEPT" ];

    rr:subjectMap [
        rr:template "department/{DEPTNO}";
        rr:class ex:Department ;
    ];

    rr:predicateObjectMap [
        rr:predicate ex:location ;
        rr:objectMap [
            rr:parentTriplesMap  <#SiteTriplesMap> ;
        ];
    ]
.
<#SiteTriplesMap>
    rr:logicalTable [ rr:tableName "DEPT" ];

    rr:subjectMap [
        rr:template "site/{LOC}";
        rr:class ex:Site ;
    ];

    rr:predicateObjectMap [
        rr:predicate ex:siteName ;
        rr:objectMap [
            rr:column "LOC" ;
        ];
    ]
.
BenjaminHofstetter commented 1 year ago

i have the the following xml input.

<?xml version="1.0" encoding="UTF-8"?>
<locations xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" export-time="2023-05-24T07:01:00+01:00" xsi:schemaLocation="http://www.hydrodaten.admin.ch/lhg/az/xml/hydroweb2.xsd">
  <station name="Adelboden" easting="608710" northing="148300" number="2232" water-body-name="Allenbach" water-body-type="river">
    <parameter name="Pegel m ü. M." unit="m" field-name="BAFU_2232_PegelRadarunten">
      <datetime>2023-05-24T07:50:00+01:00</datetime>
      <value>1297.981</value>
      <max-24h>1298.311</max-24h>
      <mean-24h>1298.034</mean-24h>
      <min-24h>1297.952</min-24h>
    </parameter>
    <parameter name="Abfluss m3/s" unit="m3/s" field-name="BAFU_2232_AbflussRadarunten">
      <datetime>2023-05-24T07:50:00+01:00</datetime>
      <value hq-class="1" quantile-class="3" warn-level-class="1">3.141</value>
      <max-24h hq-class="1" quantile-class="5" warn-level-class="1">10.945</max-24h>
      <mean-24h>4.107</mean-24h>
      <min-24h>2.786</min-24h>
    </parameter>
    <parameter name="Wassertemperatur" unit="°C" field-name="BAFU_2232_Wassertemperatur1">
      <datetime>2023-05-24T07:50:00+01:00</datetime>
      <value temperature-class="2">6.380</value>
      <max-24h temperature-class="3">10.300</max-24h>
      <mean-24h>7.379</mean-24h>
      <min-24h>6.010</min-24h>
    </parameter>
  </station>
</locations>

The goal is to produce that ....

Screenshot 2023-06-07 at 11 17 29

In xrm i have two sources...

logical-source StationSource {
    type xml
    source "stdin" // use stdin if you plan to read from standard inputs, for example with CARML
    iterator "/locations/station"

    referenceables
        id "@number"
        name "@name"
}

logical-source ParameterSource {
    type xml
    source "stdin" // use stdin if you plan to read from standard inputs, for example with CARML
    iterator "/locations/station/parameter"

    referenceables
        id "@field-name"
        comment "@name"
}

The mapping looks like this ....

output carml // choose from carml, rml, r2rml, csvw etc  

map stationMapping from StationSource { 
    subject template stationIri with id ;

    types
        ex.Station

    properties
        ex.name from name ;
        ex.id from id ;
        ex.hasParameter parent-map parameterMapping ;
}

map parameterMapping from ParameterSource { 
    subject template parameterIri with id ;

    types
        ex.Parameter

    properties
        ex.id from id ;
        ex.comment from comment ;
}

the line ex.hasParameter parent-map parameterMapping ; is almost doing what i need. it generates the following RML.

rr:predicateObjectMap [
        rr:predicate ex:hasParameter;
        rr:objectMap [
            rr:parentTriplesMap  <#parameterMapping>
        ]
    ].

what is missing here is the joinCondition. it should be like that.

rr:predicateObjectMap [
        rr:predicate ex:hasParameter;
        rr:objectMap [
            rr:parentTriplesMap  <#parameterMapping> ;
            rr:joinCondition [
                    rr:child "@number";
                    rr:parent "../@number";
            ];
        ]
    ].

a few hints... rr:joinCondition is needed because we have two sources (iterators). and i have found this ... " The child expression is evaluated on the current source, and the parent expression is evaluated on the source to be joined."

The terms parent and child are very confusing for me.

BenjaminHofstetter commented 1 year ago

demo repo https://github.com/BenjaminHofstetter/xrm-parentTriplesMap

ktk commented 8 months ago

I have the same use-case for a potential client. In other words I would give this issue priority, I think it will be useful for various scenarios.

mchlrch commented 8 months ago

The necessary changes to support declaring one or more rr:joinConditions have now been implemented in XRM.

Working example: Starting out from the example in the demo repository ...

demo repo https://github.com/BenjaminHofstetter/xrm-parentTriplesMap

... and applying the following changes:

logical-source ParameterSource {
        referenceables
                id "@field-name"
                comment "@name"
+               stationId "../@number"
 }
map stationMapping from StationSource {
        properties
                ex.name from name ;
                ex.id from id ;
-               ex.hasParameter parent-map parameterMapping ;
+               ex.hasParameter parent-map parameterMapping join id with stationId ;
 }

image

ktk commented 8 months ago

Great! I will have an XML to try it out as well, will talk to you next week :)

mchlrch commented 8 months ago

Resolved in xrm version 1.5.0