3

我想将 CSV 转换为 RDF。

实际上,该 CSV 的一列是一组用分隔符(在我的例子中是空格字符)连接的值。

这是一个示例 CSV(带标题):

col1,col2,col3
"A","B C D","John"
"M","X Y Z","Jack"

我希望在转换过程中创建一个类似这样的 RDF:

:A :aProperty :B, :C, :D; :anotherProperty "John".
:M :aProperty :X, :Y, :Z; :anotherProperty "Jack".

我通常使用 Tarql 进行 CSV 转换。
每行迭代都很好。
但它没有对“内部”列值进行子迭代的功能。

SPARQL-Generate 可能会有所帮助(据我所知,使用 iter:regex 和 sub-generate)。但是我找不到任何与我的用例匹配的示例。

PS:可能RML也可以提供帮助。但我对这项技术没有先验知识。

4

3 回答 3

5

您可以使用RMLFnO完成此操作。

首先,我们需要访问可以用 RML 完成的每一行。RML 允许您使用LogicalSource遍历 CSV 文件 ( ql:CSV) 的 每一行。不需要指定迭代器( ),因为 RML 中的默认迭代器是基于行的迭代器。这导致以下 RDF(Turtle):rml:iterator

<#LogicalSource>
    a rml:LogicalSource;
    rml:source "data.csv";
    rml:referenceFormulation ql:CSV.

实际上三元组是在TriplesMap的帮助下生成的,它使用 LogicalSource 从每个 CSV 行中检索数据:

<#MyTriplesMap>
    a rr:TriplesMap;
    rml:logicalSource <#LogicalSource>;

    rr:subjectMap [
        rr:template "http://example.org/{col1}";
    ];

    rr:predicateObjectMap [
        rr:predicate ex:aProperty;
        rr:objectMap <#FunctionMap>;
    ];

    rr:predicateObjectMap [
        rr:predicate ex:anotherProperty;
        rr:objectMap [
            rml:reference "col3";
        ];
    ].

col3CSV 列用于创建以下三元组:

<http://example.org/A> <http://example.org/ns#anotherProperty> "John".

col2但是,需要先拆分CSV 列中的字符串。这可以通过 Fno(函数本体)和支持 FnO 函数执行的 RML 处理器来实现。这种 RML 处理器可以是 RML Mapper,但也可以使用其他处理器。需要以下 RDF 来调用 FnO 函数,该函数将输入字符串以空格作为分隔符,并将我们的 LogicalSource 作为输入数据:

<#FunctionMap>
    fnml:functionValue [
        rml:logicalSource <#LogicalSource>; # our LogicalSource
        rr:predicateObjectMap [
            rr:predicate fno:executes; 
            rr:objectMap [ 
                rr:constant grel:string_split # function to use
            ];
        ];
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter;
            rr:objectMap [ 
                rml:reference "col2" # input string
            ];
        ];
        rr:predicateObjectMap [
            rr:predicate grel:p_string_sep;
            rr:objectMap [ 
                rr:constant " "; # space separator
            ];
        ];
    ].

RML 映射器支持的 FnO 函数可在此处获得: https ://rml.io/docs/rmlmapper/default-functions/ 您可以在该页面上找到函数名称及其参数。

映射规则

@base <http://example.org> .
@prefix rml: <http://semweb.mmlab.be/ns/rml#> .
@prefix rr: <http://www.w3.org/ns/r2rml#> .
@prefix ql: <http://semweb.mmlab.be/ns/ql#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix fnml: <http://semweb.mmlab.be/ns/fnml#> .
@prefix fno: <https://w3id.org/function/ontology#> .
@prefix grel: <http://users.ugent.be/~bjdmeest/function/grel.ttl#> .
@prefix ex: <http://example.org/ns#> .

<#LogicalSource>
    a rml:LogicalSource;
    rml:source "data.csv";
    rml:referenceFormulation ql:CSV.


<#MyTriplesMap>
    a rr:TriplesMap;
    rml:logicalSource <#LogicalSource>;

    rr:subjectMap [
        rr:template "http://example.org/{col1}";
    ];

    rr:predicateObjectMap [
        rr:predicate ex:aProperty;
        rr:objectMap <#FunctionMap>;
    ];

    rr:predicateObjectMap [
        rr:predicate ex:anotherProperty;
        rr:objectMap [
            rml:reference "col3";
        ];
    ].

<#FunctionMap>
    fnml:functionValue [
        rml:logicalSource <#LogicalSource>;
        rr:predicateObjectMap [
            rr:predicate fno:executes; 
            rr:objectMap [ 
                rr:constant grel:string_split 
            ];
        ];
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter;
            rr:objectMap [ 
                rml:reference "col2" 
            ];
        ];
        rr:predicateObjectMap [
            rr:predicate grel:p_string_sep;
            rr:objectMap [ 
                rr:constant " ";
            ];
        ];
    ].

输出

<http://example.org/A> <http://example.org/ns#aProperty> "B".
<http://example.org/A> <http://example.org/ns#aProperty> "C".
<http://example.org/A> <http://example.org/ns#aProperty> "D".
<http://example.org/A> <http://example.org/ns#anotherProperty> "John".
<http://example.org/M> <http://example.org/ns#aProperty> "X".
<http://example.org/M> <http://example.org/ns#aProperty> "Y".
<http://example.org/M> <http://example.org/ns#aProperty> "Z".
<http://example.org/M> <http://example.org/ns#anotherProperty> "Jack".

注意:我为 RML 及其技术做出了贡献。

于 2020-04-23T06:50:27.783 回答
2

您可以在操场上测试此查询https://ci.mines-stetienne.fr/sparql-generate/playground.html并检查其行为是否符合预期:

BASE <http://data.example.com/> 
PREFIX : <http://example.com/> 
PREFIX iter: <http://w3id.org/sparql-generate/iter/>
PREFIX fun: <http://w3id.org/sparql-generate/fn/>

GENERATE { 
  <{?col1}> :anotherProperty ?col3.
  GENERATE{
      <{?col1}> :aProperty <{ ?value }> ; 
  }
  ITERATOR iter:Split( ?col2 , " " ) AS ?value .
}
ITERATOR iter:CSVStream("http://example.com/file.csv", 20, "*") AS ?col1 ?col2 ?col3
于 2018-12-11T00:01:44.090 回答
0

表格数据模型和相关规范针对此用例,尽管我记得,我们没有提供组合valueUrl以及separator让子列生成多个 URI。

描述这一点的元数据将类似于以下内容:

{
  "@context": "http://www.w3.org/ns/csvw",
  "url": "test.csv",
  "tableSchema": {
    "columns": [{
      "name": "col1",
      "titles": "col1",
      "datatype": "string",
      "required": true
    }, {
      "name": "col2",
      "titles": "col2",
      "datatype": "string",
      "separator": " "
    }, {
      "name": "col3",
      "titles": "col3",
      "datatype": "string",
      "propertyUrl": "http://example.com/anotherProperty",
      "valueUrl": "http://example.com/{col3}"
    }],
    "primaryKey": "col1",
    "aboutUrl": http://example.com/{col1}"
  }
}
于 2018-12-11T21:07:58.263 回答