RMLio / rmlmapper-java

The RMLMapper executes RML rules to generate high quality Linked Data from multiple originally (semi-)structured data sources
http://rml.io
MIT License
147 stars 61 forks source link

Prevent slash encoding (escape) in rr:subjectMap rr:template #240

Closed rppala3 closed 3 days ago

rppala3 commented 4 weeks ago

I'm using rmlmapper-java v7.0.0.

Given this rule

rr:subjectMap [
  rr:class ex:Session;
  rr:template "http://example.com/{@fullpath}";
];

where fullpath = "course/xyz/unit/1/session/3". Is it possible prevent the encoding of the slashes in %2F? Unfortunately, the rr:subjectMap rr:termType only includes rr:IRI and rr:BlankNode, but not rr:Literal

Actual result:

<http://example.com/course%2Fxyz%2Funit%2F1%2Fsession%2F3> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com#Session> .

Desidered result:

<http://example.com/course/xyz/unit/1/session/3> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.com#Unit> .
DylanVanAssche commented 1 week ago

Hi!

If you use a template, it will always percent-encode the variables when the term type is IRI as specified in the RML specification.

To achieve what you want, you can use a FnO function to concat the values as strings. For example:

# Unique IRI generation: $stationId#$generatedAtTime
rr:subjectMap [
  fnml:functionValue [
      rr:predicateObjectMap [
          rr:predicate fno:executes ;
          rr:objectMap [ rr:constant idlab-fn:concat ]
      ];
      rr:predicateObjectMap [
          rr:predicate idlab-fn:str ;
          rr:objectMap [ rr:constant "http://example.com/" ]
      ];
      rr:predicateObjectMap [
          rr:predicate idlab-fn:otherStr ;
          rr:objectMap [ rml:reference "@fullpath" ]
      ];
      rr:predicateObjectMap [
           rr:predicate idlab-fn:delimiter ;
           rr:objectMap [ rr:constant "" ]
      ];
  ];
  rr:termType rr:IRI;
];
rppala3 commented 3 days ago

Thank you vey much @DylanVanAssche. The snippet you provided me works very well, but I realised that idlab-fn:concat accepts two strings only. I'm trying to concatenate multiple strings using idlab-fn:concatSequence, but I cannot find the proper syntax to declare a idlab-fn:_seq of parameters.

Example of templete: __BASE_URI__/{@parent-fullpath}/unit/{@index} My parts are ['__BASE_URI__', '@parent-fullpath', 'unit', '@index'] respectively constant, reference,constant, reference with "/" as delimiter.

Any suggestion?

DylanVanAssche commented 3 days ago

You need to make an RDF Sequence, can you share your snippet that you are trying to write?

An RDF Sequence looks like this:

idlab-fn:_seq [ a rdf:Seq;
  rdf:_1 "__BASE_URI__";
  rdf:_2 "@parent-fullpath";
  rdf:_3 "unit";
  rdf:_4 "@index";
]

See https://stackoverflow.com/questions/30529932/how-to-define-the-type-of-elements-in-an-rdfseq

rppala3 commented 3 days ago

Thanks.

I had already read that post on stackoverflow, but I was having trouble to find the exact RML syntax. After several attempts, I found the right one.

The snippet below works as expected.

fnml:functionValue [
  rr:predicateObjectMap [
    rr:predicate fno:executes;
    rr:objectMap [ rr:constant idlab-fn:concatSequence ];
  ];
  rr:predicateObjectMap [
    rr:predicate rdf:_1;
    rr:objectMap [ rr:constant "__BASE_URI__" ];
  ];
  rr:predicateObjectMap [
    rr:predicate rdf:_2;
    rr:objectMap [ rml:reference "@parent-fullpath" ];
  ];
  rr:predicateObjectMap [
    rr:predicate rdf:_3;
    rr:objectMap [ rr:constant "unit" ];
  ];
  rr:predicateObjectMap [
    rr:predicate rdf:_4;
    rr:objectMap [ rml:reference "@index" ];
  ];
  rr:predicateObjectMap [
    rr:predicate idlab-fn:delimiter;
    rr:objectMap [ rr:constant "/" ];
  ];
];

I guess we can close the issue.
Many thanks for the support.