Trouble with R2ML syntax: no triples map found

Initially I was using the following Stardog Mapping rule''

loc:{"LOCATIONNAME"} a loc:CompanyBuilding ;
    loc:name "{\"LOCATIONNAME\"}";
    loc:locatedIn loc:"{\"CITY\"}";
    sm:map [
       sm:query """
        SELECT LOCATIONNAME, CITY, PROVINCE, COUNTRY
        FROM LOCATION
        """ ;
    ] 

The issue is that the CITY may not be unique and to make it unique I need something like CITY_PROVINCE_COUNTRY. This could be achieved by adding CONCAT in my SQL statement but I found it messy. Having had use R2ML in the pass with Stardog, I new this could be done in a very readable manner. So I converted my rule to the following

<#BuildingMapping>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/companybuilding/{LOCATIONNAME}";
        rr:class loc:CompanyBuilding;
    ];
    rr:predicateObjectMap [
        rr:predicate loc:name;
        rr:objectMap [ rr:column "LOCATIONNAME"];
    ];
    rr:predicateObjectMap [
        rr:predicate loc:locatedIn;
        rr:objectMap [ rr:template "http://topology/location/city/{CITY}_{PROV}_{COUNTRY}"];
    ].

I get the following

There were no triples maps found in the mappings file. Is this a Stardog Mapping Syntax file?

Looking at the R2ML RFC and example, my file seems correct. What am I missing.

Hi Serge,

Did you specify the --format as r2rml when creating your virtual graph?

As a side note, might I recommend the bright shiny Stardog Mapping Syntax 2 for all your VG needs?

MAPPING <urn:building>
FROM SQL {
    SELECT LOCATIONNAME, CITY, PROVINCE, COUNTRY
    FROM LOCATION
}
TO {
    ?lociri a loc:CompanyBuilding ;
        loc:name ?LOCATIONNAME ;
        loc:locatedIn ?cityiri .   
}
WHERE {
    BIND(template("http://topology/location/companybuilding/{LOCATIONNAME}") as ?lociri)
    BIND(template("http://topology/location/city/{CITY}_{PROVINCE}_{COUNTRY}") as ?cityiri)
}

Will it be possible to have the shiny SMS2 translated to R2RML? In other words: Could one have a tool that reads SMS2 and produces R2RML?

Tried the new shiny SMS, but I get

 stardog-admin virtual import Topology location.properties location.ttl  
Expected ':', found ' ' [L10]

My files looks like

@prefix rr: &lt;http://www.w3.org/ns/r2rml#&gt; .
@prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; .
@prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .
@prefix loc: &lt;http://topology/location&gt; .
@prefix sm: &lt;tag:stardog:api:mapping:&gt; .
@prefix wgs: &lt;http://www.w3.org/2003/01/geo/wgs84_pos#&gt; .
@prefix geo: &lt;http://www.opengis.net/ont/geosparql#&gt; .
@prefix : &lt;http://blog.stardog.com/geons/&gt; .

MAPPING &lt;urn:building&gt;
FROM SQL {
   SELECT LOCATIONNAME, CITY, PROVINCE, COUNTRY
   FROM LOCATION
}

TO {
  ?lociri a loc:CompanyBuilding ;
  loc:name ?LOCATIONNAME ;
  loc:locatedIn ?cityiri .
}
WHERE {  
  BIND(template("http://topology/location/companybuilding/{LOCATIONNAME}") as ?lociri)
  BIND(template("http://topology/location/city/{CITY}_{PROVINCE}_{COUNTRY}") as ?cityiri)
}

FYI --format r2rml work for my r2rml definition. Thanks

Yes, once the mapping is in your system, you can export r2rml mappings on the CLI:

✔ stephen:community ➭ stardog-admin virtual mappings --format r2rml vg
@prefix : <http://api.stardog.com/> .
@prefix rr: <http://www.w3.org/ns/r2rml#> .
@prefix stardog: <tag:stardog:api:> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix fn: <http://www.w3.org/2005/xpath-functions#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<tag:stardog:api:mapping:generated:mapping-1334689266> a rr:TriplesMap ;
    rr:subjectMap [
        rr:template "http://topology/location/companybuilding/{`LOCATIONNAME`}" ;
            rr:termType rr:IRI
    ] ;
    rr:predicateObjectMap [
        rr:objectMap [
            rr:datatype xsd:string ;
                rr:column "`LOCATIONNAME`"
        ] ;
            rr:predicateMap [
                rr:constant <http://topology/location/name>
            ]
    ] ;
    rr:logicalTable [
        rr:sqlQuery """SELECT *
FROM `LOCATION`"""
    ] ;
    rr:predicateObjectMap [
        rr:predicateMap [
            rr:constant <http://topology/location/locatedIn>
        ] ;
            rr:objectMap [
                rr:termType rr:IRI ;
                    rr:template "http://topology/location/city/{`CITY`}_{`PROVINCE`}_{`COUNTRY`}"
            ]
    ] , [
        rr:predicateMap [
            rr:constant rdf:type
        ] ;
            rr:objectMap [
                rr:constant <http://topology/location/CompanyBuilding>
            ]
    ] .

You may have needed --format sms2 in your virtual import command. But regardless I'm glad you were able to get your mapping loaded!

I know why @matthias ask the question and I am somewhat interested in the answer for the same reason. In the past, I would refrain from using SMS since I wanted to stick with a standard, and honestly SMS did not bring that much more to the table.

Today I tried SMS2, and I have to admit that it much easier to use, less verbose (in this case 40% less) and easier to read. What I like is that I was able to group many class instance creation in a single group. The ROI may be worth diverging from standard, but still undecided. If a tool like @matthias ask exists, then it would be a no brainer.

For the curious, Bbelow you will find the R2RML and SMS2 version. If anyone knows how I can make the R2RML more consise I would be interested.

R2RML

@prefix rr: <http://www.w3.org/ns/r2rml#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix loc: <http://topology/location> .
@prefix sm: <tag:stardog:api:mapping:> .
@prefix wgs: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
@prefix geo: <http://www.opengis.net/ont/geosparql#> .
@prefix : <http://blog.stardog.com/geons/> .

<#BuildingGeoMapping>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/geo/{LOCATIONNAME}";
        rr:class geo:Geometry;
    ];
    rr:predicateObjectMap [
        rr:predicate wgs:lat;
        rr:objectMap [ rr:column "COORDINATEX"];
    ];
    rr:predicateObjectMap [
        rr:predicate wgs:long;
        rr:objectMap [ rr:column "COORDINATEY"];
    ];


<#BuildingMapping>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/companybuilding/{LOCATIONNAME}";
        rr:class loc:CompanyBuilding;
    ];
    rr:predicateObjectMap [
        rr:predicate loc:name;
        rr:objectMap [ rr:column "LOCATIONNAME"];
    ];
    rr:predicateObjectMap [
        rr:predicate loc:locatedIn;
        rr:objectMap [ rr:template "http://topology/location/city/{CITY}_{PROVINCE}_{COUNTRY}"];
    ].
    rr:predicateObjectMap [
        rr:predicate geo:hasGeometry;
        rr:objectMap [ rr:template "http://topology/location/geo/{LOCATIONNAME}"];
    ].

<#CityMaping>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/city/{CITY}_{PROVINCE}_{COUNTRY}";
        rr:class loc:City;
    ];
    rr:predicateObjectMap [
        rr:predicate loc:name;
        rr:objectMap [ rr:column "CITY"];
    ];
    rr:predicateObjectMap [
        rr:predicate loc:locatedIn;
        rr:objectMap [ rr:template "http://topology/location/province/{PROVINCE}_{COUNTRY}"];
    ].

<#ProvMapping>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/province/{PROVINCE}_{COUNTRY}";
        rr:class loc:City;
    ];
    rr:predicateObjectMap [
        rr:predicate loc:name;
        rr:objectMap [ rr:column "PROVINCE"];
    ];
    rr:predicateObjectMap [
        rr:predicate loc:locatedIn;
        rr:objectMap [ rr:template "http://topology/location/country/{COUNTRY}"];
    ].

<#Country>
    rr:logicalTable [ rr:tableName "LOCATION"];
    rr:subjectMap [ 
        rr:template "http://topology/location/country/{COUNTRY}";
        rr:class loc:City;
    ];
    rr:predicateObjectMap [
        rr:predicate loc:name;
        rr:objectMap [ rr:column "COUNTRY"];
    ].

SMS2

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX loc: <http://topology/location#> 
PREFIX sm: <tag:stardog:api:mapping:> 
PREFIX wgs: <http://www.w3.org/2003/01/geo/wgs84_pos#> 
PREFIX geo: <http://www.opengis.net/ont/geosparql#> 
PREFIX : <http://blog.stardog.com/geons/> 

MAPPING <urn:building>
FROM SQL {
    SELECT LOCATIONNAME, ALIAS1, ADDRESS, POSTALCODE, CITY, PROVINCE, COUNTRY, COORDINATEX, COORDINATEY
    FROM LOCATION
}

TO {
?geoiri a geo:Geometry ;
wgs:lat ?COORDINATEX ;
wgs:long ?COORDINATEY .

?buildingiri a loc:CompanyBuilding ;
loc:name ?LOCATIONNAME ;
loc:alias ?ALIAS1;
loc:address ?ADDRESS;
loc:postalCode ?POSTALCODE;
loc:locatedIn ?cityiri .


?cityiri a loc:City ;
loc:name ?CITY ;
loc:locatedIn ?proviri .

?proviri a loc:Province ;
loc:name ?PROVINCE ;
loc:locatedIn ?countryiri .

?countryiri a loc:Country ;
loc:name ?COUNTRY ;
}
WHERE {  
    BIND(template("http://topology/location/companybuilding/{LOCATIONNAME}") as ?buildingiri)
    BIND(template("http://topology/location/geo/{LOCATIONNAME}") as ?geoiri)
    BIND(template("http://topology/location/city/{CITY}_{PROVINCE}_{COUNTRY}") as ?cityiri)
    BIND(template("http://topology/location/prov/{PROVINCE}_{COUNTRY}") as ?proviri)
    BIND(template("http://topology/location/country/{COUNTRY}") as ?countryiri)
}

And if you read other reply you can load the SMS2 version above and then convert it to a standard R2RML file having best of both worlds.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.