Mapping 对于输入的一个数据元素(单元)中的多个复杂实体,RML中是否有一种解决方案,而无需清理输入数据?

Mapping 对于输入的一个数据元素(单元)中的多个复杂实体,RML中是否有一种解决方案,而无需清理输入数据?,mapping,rdf,rml-rdf,Mapping,Rdf,Rml Rdf,我有一个人名列表,例如,除了(person是列名): 请注意,多人以不同的方式被提及,并且分开的方式也不同 我想使用RDF映射语言创建以下RDF,而无需清理(或更改)输入数据: :Wilson a foaf:Person; foaf:firstName "Charles"; foaf:lastName "Wilson" . :Harris a foaf:Person; foaf:firstName "Arthur"; foaf:lastName "Harris"

我有一个人名列表,例如,除了(
person
是列名):

请注意,多人以不同的方式被提及,并且分开的方式也不同

我想使用RDF映射语言创建以下RDF,而无需清理(或更改)输入数据:

:Wilson a foaf:Person;
    foaf:firstName "Charles";
    foaf:lastName "Wilson" .

:Harris a foaf:Person;
    foaf:firstName "Arthur";
    foaf:lastName "Harris" .

:White a foaf:Person;
    foaf:firstName "D.";
    foaf:lastName "White" .
请注意,输入数据中提到了Arthur Harris两次,但只创建了一个RDF资源

我使用函数本体并创建了一个自定义java方法。根据参数
mode
返回人员属性列表(例如,仅返回URI或仅返回名字)

公共静态列表getPersons(字符串值,字符串模式){
if(mode==null | | value.trim().isEmpty())
返回数组。asList();
列表结果=新建ArrayList();
for(个人p:getAllPersons(价值)){
if(mode.trim().isEmpty()| | mode.equals(“URI”)){
结果。添加(”http://example.org/person/“+p.getLastName());
}else if(mode.equals(“firstName”)){
results.add(p.getFirstName());
}else if(mode.equals(“lastName”)){
results.add(p.getLastName());
}else if(mode.equals(“全名”)){
results.add(p.getFullName());
}
}
返回结果;
}
假设
getAllPersons
方法正确地从给定字符串中提取人员,如上面所述。 为了从一个单元格中提取多个人,我调用
subjectMap
中的
getPersons
函数,如下所示:

:tripleMap a rr:TriplesMap .
:tripleMap rml:logicalSource :ExampleSource .
:tripleMap rr:subjectMap [
    fnml:functionValue [

        rr:predicateObjectMap [
            rr:predicate fno:executes ;
            rr:objectMap [ rr:constant cf:getPersons ]
        ] ;
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter ;
            rr:objectMap [ rml:reference "Person" ] # the column name
        ] ;
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter2 ;
            rr:objectMap [ rr:constant "URI" ] # the mode
        ]
    ];
    rr:termType rr:IRI ;
    rr:class foaf:Person
] .
:Wilson a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .

:Harris a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .

:White a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .
我使用RMLMapper,但是,它只允许为每行返回一个主题,请参阅。 这就是为什么我编写了一个
List getSubjects(Term triplemap,Mapping,Record Record,inti)
方法并相应地替换了它。 这将导致以下结果:

:Wilson a foaf:Person .

:Harris a foaf:Person .

:White a foaf:Person .
我知道此扩展与RML规范不兼容,其中规定了以下内容:

它[三元组映射]必须正好有一个主题映射,用于指定如何为逻辑源(相应的数据库/CSV/XML/JSON数据源)的每一行/记录/元素/对象生成主题

如果我继续添加名字resp。姓氏,可以添加以下
predicateObjectMap

:tripleMap rr:predicateObjectMap [
    rr:predicate foaf:firstName;
    rr:objectMap [
        fnml:functionValue [

            rr:predicateObjectMap [
                rr:predicate fno:executes ;
                rr:objectMap [ rr:constant cf:getPersons ]
            ] ;
            rr:predicateObjectMap [
                rr:predicate grel:valueParameter ;
                rr:objectMap [ rml:reference "Person" ] # the column name
            ] ;
            rr:predicateObjectMap [
                rr:predicate grel:valueParameter2 ;
                rr:objectMap [ rr:constant "firstName" ] # the mode
            ]
        ]
    ]
] .
由于为每个主题计算了一个
predicateObjectMap
,并且现在返回了多个主题,因此每个person资源将获得每个人的名字。为了更清楚,它看起来像这样:

:tripleMap a rr:TriplesMap .
:tripleMap rml:logicalSource :ExampleSource .
:tripleMap rr:subjectMap [
    fnml:functionValue [

        rr:predicateObjectMap [
            rr:predicate fno:executes ;
            rr:objectMap [ rr:constant cf:getPersons ]
        ] ;
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter ;
            rr:objectMap [ rml:reference "Person" ] # the column name
        ] ;
        rr:predicateObjectMap [
            rr:predicate grel:valueParameter2 ;
            rr:objectMap [ rr:constant "URI" ] # the mode
        ]
    ];
    rr:termType rr:IRI ;
    rr:class foaf:Person
] .
:Wilson a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .

:Harris a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .

:White a foaf:Person;
    foaf:firstName "Charles" ;
    foaf:firstName "Arthur" ;
    foaf:firstName "D." .
我的问题是:对于输入的一个数据元素(单元格)中的多个复杂实体(例如,有名字和姓氏的人),RML中是否有解决方案或解决方法,而无需清理(或更改)输入数据

也许这个问题与我的问题有关:


如果这样的用例不需要像RML这样的映射框架来解决,那也没问题。如果是这样的话,还有什么替代方案?例如,生成RDF的手工提取管道?

据我所知,您尝试使用FnO函数和联接条件是不可能的

但是,您可以尝试指定一个聪明的
rml:query
rml:iterator
,在复杂值到达RMLMapper之前将其拆分。不过,这是否可能取决于特定的源数据库

例如,如果源是SQL Server数据库,则可以使用该函数。或者,如果它是PostgreSQL数据库,则可以与一起使用。(由于数据中使用了不同的分隔符,因此可能需要为每个不同的分隔符调用一次STRING_SPLIT或STRING_to_ARRAY

如果您提供有关底层数据库的更多信息,我可以用一个示例更新这个答案


(注意:我对RML及其技术做出了贡献。)

据我所知,您有一个规范化问题(多值单元格)。当然,您要求的是在1NF中有一个数据集,请参阅:

要解决CSV文件中常见的异构性问题,您可以在Web注释上使用CSV(W3C建议)。更详细地说,您在本例中要求的属性是
csvw:separator
()

然而,CSVW的解析器并不多,其用于生成RDF的属性的语义也不是很清楚。我们一直在研究一种解决方案,该解决方案使用CSVW和RML+FnO从表格数据生成虚拟KG(同时使用SPARQL查询作为输入,不将输入数据集转换为RDF)。我们提案的输出是一个格式良好的数据库,具有标准的[R2]RML映射,因此任何符合[R2]RML的数据库都可以用于回答查询或实现知识图。尽管我们目前不支持具体化步骤,但它在我们的待办事项列表中

您可以查看贡献(正在审查中):


网站:

一个聪明的迭代器是不可能的,因为人可以任意分开。基础数据库是一个excel文件,或者如果转换成CSV文件。我提交了一篇关于这个主题的论文,并在这里提供了一些代码(生成器、评估器):David,你的一篇论文评论提到了一个名为“q”的工具.你知道这是什么吗?还有,我应该阅读还是上面的SWJ论文包含了它?@VladimirAlexiev我认为审稿人把q称为查询语言,把kdb+称为数据库:(但不完全确定)。不,阅读SWJ论文就够了,因为它是印刷前论文的扩展和修订。