2

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

Person
"Wilson, Charles; Harris Arthur"
"White, D.
Arthur Harris"

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

我想使用 RDF 映射语言https://rml.io/创建以下 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 资源。

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

public static List<String> getPersons(String value, String mode) {
    if(mode == null || value.trim().isEmpty())
        return Arrays.asList();

    List<String> results = new ArrayList<>();
    for(Person p : getAllPersons(value)) {
        if(mode.trim().isEmpty() || mode.equals("URI")) {
            results.add("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("fullName")) {
            results.add(p.getFullName());
        }
    }

    return results;
}

假设该getAllPersons方法正确地从给定字符串中提取人员,如上面的那些。为了从一个单元格中提取多个人,我这样调用该getPersons函数subjectMap

: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
] .

我使用 RMLMapper https://github.com/RMLio/rmlmapper-java,但是,它只允许为每一行返回一个主题,请参阅https://github.com/RMLio/rmlmapper-java/blob/master/src /main/java/be/ugent/rml/Executor.java#L292。这就是为什么我写了一个List<ProvenancedTerm> getSubjects(Term triplesMap, Mapping mapping, Record record, int i)方法并相应地替换了它。这导致以下结果:

:Wilson a foaf:Person .

:Harris a foaf:Person .

:White a foaf:Person .

我知道此扩展与 RML 规范https://rml.io/specs/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为每个主题评估 a 并且现在返回多个主题,所以每个 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 中是否有解决方案或变通方法,而无需清理(或更改)输入数据?

也许这个问题与我的问题有关:https ://www.w3.org/community/kg-construct/track/issues/3

如果这样的用例不打算通过像 RML 这样的映射框架来解决,那也很好。如果是这种情况,还有什么替代方案?例如,生成 RDF 的手工提取管道?

4

2 回答 2

2

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

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

例如,如果源是 SQL Server 数据库,您可以使用函数STRING_SPLIT。或者,如果它是 PostgreSQL 数据库,您可以将STRING_TO_ARRAYunnest一起使用。(由于数据中使用了不同的分隔符,您可能必须为每个不同的分隔符调用一次 STRING_SPLIT 或 STRING_TO_ARRAY。

如果您提供有关基础数据库的更多信息,我可以通过示例更新此答案

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

于 2020-05-26T08:50:47.177 回答
0

据我了解,您有一个标准化问题(多值单元格)。当然,您要求的是在 1NF 中有一个数据集,请参阅:https ://en.wikipedia.org/wiki/First_normal_form

要解决 CSV 文件中这些常见的异质性问题,您可以使用 CSV on the Web annotations(W3C 推荐)。更详细地说,在这种情况下您要求的属性是csvw:separatorhttps://www.w3.org/TR/tabular-data-primer/#sequence-values)。

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

您可以查看贡献(现在正在审查中):http ://www.semantic-web-journal.net/content/enhancing-virtual-ontology-based-access-over-tabular-data-morph-csv

网站:https ://morph.oeg.fi.upm.es/tool/morph-csv

于 2020-06-29T15:11:39.787 回答