Skip to content

Commit

Permalink
Merge pull request #49 from kg-construct/rmlStrategy
Browse files Browse the repository at this point in the history
Included RML Strategy, fixed some mistakes, and updated sources to respect RML-IO
  • Loading branch information
chrdebru authored Oct 13, 2024
2 parents 4a3be2f + 70f3932 commit 90ab040
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 150 deletions.
4 changes: 2 additions & 2 deletions ontology/rml-cc.owl
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ foaf:name rdf:type owl:AnnotationProperty .
:strategy rdf:type owl:ObjectProperty ;
rdfs:domain :GatherMap ;
rdfs:range :Strategy ;
rdfs:comment "A Strategy element to indicate how to perform an action (e.g. gather for collections and containers, join)."@en ;
rdfs:comment "A Strategy element to indicate how to perform an action."@en ;
rdfs:isDefinedBy <http://w3id.org/rml/cc/> ;
rdfs:label "strategy" .

Expand Down Expand Up @@ -142,7 +142,7 @@ foaf:name rdf:type owl:AnnotationProperty .

### http://w3id.org/rml/Strategy
:Strategy rdf:type owl:Class ;
rdfs:comment "Denotes a strategy to perform a action (e.g. gather for collections and containers, joins)."@en ;
rdfs:comment "Denotes a strategy to perform an action or process."@en ;
rdfs:isDefinedBy <http://w3id.org/rml/cc/> ;
rdfs:label "Strategy" .

Expand Down
186 changes: 90 additions & 96 deletions spec/rendered.html

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions spec/section/considerations.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The following mapping:
rml:predicateObjectMap [
rml:predicate ex:with ;
rml:objectMap [
rml:template "seq/{id}" ;
rml:template "seq{id}" ;
rml:gather ( [ rml:reference "values.*" ; ] ) ;
rml:gatherAs rdf:Seq ;
] ;
Expand All @@ -35,9 +35,9 @@ The following mapping:
will yield the following output:

<pre class="ex-output">
:a ex:with :seq/a . :seq/a rdf:_1 "1" ; rdf:_2 "2" , rdf:_3 "3" .
:b ex:with :seq/b . :seq/b rdf:_1 "4" ; rdf:_2 "5" , rdf:_3 "6" .
:c ex:with :seq/c . :seq/c rdf:_1 "7" ; rdf:_2 "8" , rdf:_3 "9" .
:a ex:with :seqa . :seqa rdf:_1 "1" ; rdf:_2 "2" , rdf:_3 "3" .
:b ex:with :seqb . :seqb rdf:_1 "4" ; rdf:_2 "5" , rdf:_3 "6" .
:c ex:with :seqc . :seqc rdf:_1 "7" ; rdf:_2 "8" , rdf:_3 "9" .
</pre>


Expand Down Expand Up @@ -91,7 +91,7 @@ With the following predicate mapping:
rml:predicateObjectMap [
rml:predicate ex:with ;
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:gather ( [ rml:reference "values.*" ; ] ) ;
rml:gatherAs rdf:List ;
] ;
Expand All @@ -101,8 +101,8 @@ With the following predicate mapping:
The processor must generate the following output:

<pre class="ex-output">
:a ex:with :list/a . :list/a rdf:first "1" ; rdf:rest ("2" "3" "7" "8" "9") .
:b ex:with :list/b . :list/b rdf:first "4" ; rdf:rest ("5" "6") .
:a ex:with :lista . :lista rdf:first "1" ; rdf:rest ("2" "3" "7" "8" "9") .
:b ex:with :listb . :listb rdf:first "4" ; rdf:rest ("5" "6") .
</pre>

It is assumed that a processor will concatenate the collections or containers while respecting the order of the iterations as provided by the logical source.
Expand Down Expand Up @@ -147,7 +147,7 @@ Now, when an `rml:template`, `rml:constant` or `rml:reference` is provided, to a
If we add an `rml:template` in the object map:
<pre class="ex-mapping">
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:gather ( [ rml:reference "a.*" ] [ rml:reference "b.*" ]) ;
rml:gatherAs rdf:List ;
rml:strategy rml:cartesianProduct ;
Expand Down Expand Up @@ -187,7 +187,7 @@ Let's consider the following document and mapping:
rml:predicateObjectMap [
rml:predicate ex:with ;
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:gather ( [ rml:reference "values1.*" ; ] [ rml:reference "values2.*" ; ] ) ;
rml:gatherAs rdf:List ;
] ;
Expand All @@ -199,17 +199,17 @@ Furthermore, the lists generated for id `"a"` must be concatenated since they sh
The expected output is:

<pre class="ex-output">
:a ex:with :list/a .
:list/a rdf:first "1" ; rdf:rest ("a" "b" "5" "6" "e") .
:b ex:with :list/b .
:list/b rdf:first "3" ; rdf:rest ("4" "c" "d") .
:a ex:with :lista .
:lista rdf:first "1" ; rdf:rest ("a" "b" "5" "6" "e") .
:b ex:with :listb .
:listb rdf:first "3" ; rdf:rest ("4" "c" "d") .
</pre>

Now let's change the default strategy to `rml:cartesianProduct`:

<pre class="ex-mapping">
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:gather ( [ rml:reference "values1.*" ; ] [ rml:reference "values2.*" ; ] ) ;
rml:gatherAs rdf:List ;
rml:strategy rml:cartesianProduct ;
Expand All @@ -227,8 +227,8 @@ But again, these lists must be concatenated since they share the same head node
Therefore, the processor must now generate the following output:

<pre class="ex-output">
:a ex:with :list/a .
:list/a rdf:first "1" ; rdf:rest ("a" "1" "b" "5" "e" "6" "e") .
:b ex:with :list/b .
:list/b rdf:first "3" ; rdf:rest ("c" "3" "d" "4" "c" "4" "d") .
:a ex:with :lista .
:lista rdf:first "1" ; rdf:rest ("a" "1" "b" "5" "e" "6" "e") .
:b ex:with :listb .
:listb rdf:first "3" ; rdf:rest ("c" "3" "d" "4" "c" "4" "d") .
</pre>
49 changes: 26 additions & 23 deletions spec/section/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ In other words, when the following predicate object map is used:
rml:predicateObjectMap [
rml:predicate ex:with ;
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:allowEmptyListAndContainer true ;
rml:gather ( [ rml:reference "values.*" ; ] ) ;
rml:gatherAs rdf:List ;
Expand All @@ -58,12 +58,12 @@ then the document with `"id": "d"` entails an empty list, that is a list whose h
We expect the following output where

<pre class="ex-output">
:a ex:with :list/a .
:list/a rdf:first "1" ; rdf:rest ("2" "3") .
:b ex:with :list/b .
:list/b rdf:first "4" ; rdf:rest ("5" "6") .
:c ex:with :list/c .
:list/c rdf:first "7" ; rdf:rest ("8" "9") .
:a ex:with :lista .
:lista rdf:first "1" ; rdf:rest ("2" "3") .
:b ex:with :listb .
:listb rdf:first "4" ; rdf:rest ("5" "6") .
:c ex:with :listc .
:listc rdf:first "7" ; rdf:rest ("8" "9") .
:d ex:with () .
</pre>

Expand Down Expand Up @@ -94,7 +94,7 @@ The following mapping will relate instances of authors to names. The names of au
<pre class="ex-mapping">
<#AuthorTM>
rml:logicalTable [ rml:tableName "AUTHOR" ; ] ;
rml:subjectMap [ rml:template "/person/{ID}" ; ] ;
rml:subjectMap [ rml:template "/person{ID}" ; ] ;
rml:predicateObjectMap [
rml:predicate ex:name ;
rml:objectMap [
Expand All @@ -111,9 +111,9 @@ The following mapping will relate instances of authors to names. The names of au
In this example we generate, for each row in table `AUTHOR`, an blank node of type `rdf:Bag`. Each such bag "gathers" values from different term maps. The execution of this mapping will produce the following result:

<pre class="ex-output">
:person/1 ex:name [ a rdf:Bag; rdf:_1 "Mary"; rdf:_2 "Shelley" ] .
:person/2 ex:name [ a rdf:Bag; rdf:_1 "Sir"; rdf:_2 "Terry"; rdf:_3 "Pratchett" ] .
:person/3 ex:name [ a rdf:Bag; rdf:_1 "Stephen"; rdf:_2 "Baxter" ] .
:person1 ex:name [ a rdf:Bag; rdf:_1 "Mary"; rdf:_2 "Shelley" ] .
:person2 ex:name [ a rdf:Bag; rdf:_1 "Sir"; rdf:_2 "Terry"; rdf:_3 "Pratchett" ] .
:person3 ex:name [ a rdf:Bag; rdf:_1 "Stephen"; rdf:_2 "Baxter" ] .
</pre>

While not shown in this example, different term maps allow to collect terms of different types: resources, literals, typed or language-tagged literals, etc. The fourth record in the table did not generate a bag, since each term map in the gather map did not yield a value.
Expand All @@ -127,7 +127,7 @@ Continuing with the [relational data example](#relationalexample), here we relat
<pre class="ex-mapping">
<#BookTM>
rml:logicalTable [ rml:tableName "BOOK" ; ] ;
rml:subjectMap [ rml:template "/book/{ID}" ; ] ;
rml:subjectMap [ rml:template "/book{ID}" ; ] ;
rml:predicateObjectMap [
rml:predicate ex:writtenBy ;
rml:objectMap [
Expand All @@ -147,8 +147,8 @@ Continuing with the [relational data example](#relationalexample), here we relat
Intuitively, we will join each record (or iteration) with data from the parent triples map. The join may yield one or more results, which are then gathered into a list. The execution of this mapping will produce the following RDF:

<pre class="ex-output">
:book/1 ex:writtenby ( :person/1 ) .
:book/2 ex:writtenby ( :person/2 :person/3 ) .
:book1 ex:writtenby ( :person1 ) .
:book2 ex:writtenby ( :person2 :person3 ) .
</pre>

In RML, it is assumed that each term map is multi-valued. That this, each term map may return one or more values. The default behavior is to append the values in the order of the term maps appearing in the gather map.
Expand All @@ -161,13 +161,16 @@ Here we exemplify the use of a term map in a subject map. Continuing with the JS
<pre class="ex-mapping">
<#TM> a rml:TriplesMap;
rml:logicalSource [
rml:source "data.json" ;
rml:referenceFormulation ql:JSONPath ;
rml:source [
a rml:RelativePathSource;
rml:root rml:MappingDirectory;
rml:path "data.json"
] ;
rml:iterator "$.*" ;
];

rml:subjectMap [
rml:template "seq/{id}" ;
rml:template "seq{id}" ;
rml:gather ( [ rml:reference "values.*" ; ] ) ;
rml:gatherAs rdf:Seq ;
] ;
Expand All @@ -181,12 +184,12 @@ Here we exemplify the use of a term map in a subject map. Continuing with the JS
The expected result is:

<pre class="ex-output">
:seq/a rdf:_1 "1" ; rdf:_2 "2" ; rdf:_3 "3" .
:seq/a prov:wasDerivedFrom &lt;data.json&gt; .
:seqa rdf:_1 "1" ; rdf:_2 "2" ; rdf:_3 "3" .
:seqa prov:wasDerivedFrom &lt;data.json&gt; .

:seq/b rdf:_1 "4" ; rdf:_2 "5" ; rdf:_3 "6" .
:seq/b prov:wasDerivedFrom &lt;data.json&gt; .
:seqb rdf:_1 "4" ; rdf:_2 "5" ; rdf:_3 "6" .
:seqb prov:wasDerivedFrom &lt;data.json&gt; .

:seq/c rdf:_1 "7" ; rdf:_2 "8" ; rdf:_3 "9" .
:seq/c prov:wasDerivedFrom &lt;data.json&gt; .
:seqc rdf:_1 "7" ; rdf:_2 "8" ; rdf:_3 "9" .
:seqc prov:wasDerivedFrom &lt;data.json&gt; .
</pre>
2 changes: 1 addition & 1 deletion spec/section/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ and only when, they appear in all capitals, as shown here.
### Document conventions {#conventions}
We assume readers have basic familiarity with RDF and RML.

In this document, examples assume
In this document, examples assume `http://example.org/` as the base IRI provided to the RML engine and
the following namespace prefix bindings unless otherwise stated:

| Prefix | Namespace |
Expand Down
20 changes: 11 additions & 9 deletions spec/section/presentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,16 @@ The associated RML mapping starts as follows:

<pre class="ex-mapping">
@prefix rml: &lt;http://w3id.org/rml/&gt;.
@prefix ql: &lt;http://semweb.mmlab.be/ns/ql#&gt;.
@prefix ex: &lt;http://example.com/ns&gt;.
@base &lt;http://example.com/ns&gt;.

<#TM> a rml:TriplesMap;
rml:logicalSource [
rml:source "data.json" ;
rml:referenceFormulation ql:JSONPath ;
rml:referenceFormulation rml:JSONPath;
rml:source [
a rml:RelativePathSource;
rml:root rml:MappingDirectory;
rml:path "data.json"
] ;
rml:iterator "$.*" ;
];

Expand Down Expand Up @@ -93,7 +95,7 @@ The following mapping:
rml:predicateObjectMap [
rml:predicate ex:with ;
rml:objectMap [
rml:template "list/{id}" ;
rml:template "list{id}" ;
rml:gather ( [ rml:reference "values.*" ; ] ) ;
rml:gatherAs rdf:List ;
] ;
Expand All @@ -103,9 +105,9 @@ The following mapping:
will yield the following output:

<pre class="ex-output">
:a ex:with :list/a . :list/a rdf:first "1" ; rdf:rest ("2" "3") .
:b ex:with :list/b . :list/b rdf:first "4" ; rdf:rest ("5" "6") .
:c ex:with :list/c . :list/c rdf:first "7" ; rdf:rest ("8" "9") .
:a ex:with :lista . :lista rdf:first "1" ; rdf:rest ("2" "3") .
:b ex:with :listb . :listb rdf:first "4" ; rdf:rest ("5" "6") .
:c ex:with :listc . :listc rdf:first "7" ; rdf:rest ("8" "9") .
</pre>

This is similar to the previous example, yet in this case the head node of each produced collection is assigned an IRI `:list/a`, `:list/b` and `:list/c`.
This is similar to the previous example, yet in this case the head node of each produced collection is assigned an IRI `:lista`, `:listb` and `:listc`.
5 changes: 4 additions & 1 deletion spec/section/vocabulary.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Gather maps are term maps that use [`rml:gather`](#rml-gather) and [`rml:gatherA
* A `rml:GatherMap` MUST have exactly one [`rml:gatherAs`](#rml-gatheras) property.
* A `rml:GatherMap` MAY have zero or exactly one [`rml:strategy`](#rml-strategy) property.

#### `rml:Strategy` {#strategyclass}

A strategy is a plan or set of actions designed to achieve a specific goal or outcome. Instances of `rml:Strategy` represent ways to perform an action such as combining two collections and containers. See [**constants**](#constants) for examples.

### Properties

Expand Down Expand Up @@ -55,7 +58,7 @@ When false, the gather map will not generate a collection or container.

Property `rml:allowEmptyListAndContainer` is optional, it takes the value **false** by default.

### Constants
### Constants {#constants}

#### `rml:append`

Expand Down

0 comments on commit 90ab040

Please sign in to comment.