如何从RDF文件中删除带有特定主题的行?

时间:2019-04-14 18:04:25

标签: file replace rdf dbpedia

我有一个文件包含乌龟语法(.ttl)中的三重RDF(主题-谓词对象),并且我还有另一个只包含一些主题的文件。

例如:

<http://dbpedia.org/resource/AlbaniaHistory> <http://www.w3.org/2000/01/rdf-schema#label> "AlbaniaHistory"@en .
<http://dbpedia.org/resource/AsWeMayThink> <http://www.w3.org/2000/01/rdf-schema#label> "AsWeMayThink"@en .
<http://dbpedia.org/resource/AlbaniaEconomy> <http://www.w3.org/2000/01/rdf-schema#label> "AlbaniaEconomy"@en .
<http://dbpedia.org/resource/AlbaniaGovernment> <http://www.w3.org/2000/01/rdf-schema#label> "AlbaniaGovernment"@en .

在另一个文件中,例如:

<http://dbpedia.org/resource/AlbaniaHistory>
<http://dbpedia.org/resource/AlbaniaGovernment>
<http://dbpedia.org/resource/Pérotin>
<http://dbpedia.org/resource/ArtificalLanguages>

我想得到:

<http://dbpedia.org/resource/AlbaniaHistory> <http://www.w3.org/2000/01/rdf-schema#label> "AlbaniaHistory"@en .
<http://dbpedia.org/resource/AlbaniaGovernment> <http://www.w3.org/2000/01/rdf-schema#label> "AlbaniaGovernment"@en .

因此,我想从第一个文件中删除主题不在第二个文件中的三元组。我怎么能得到这个?

我尝试在Java中读取arraylist中第二个文件的内容,并使用“ contain”方法检查第一个文件的每个三元组的主题是否与第二个文件中的任何行匹配,但是这样做太慢了,因为文件很大。我怎么能得到这个?

非常感谢您的帮助

1 个答案:

答案 0 :(得分:3)

在Java中,您可以使用RDF库以流方式读取/写入并进行一些基本过滤。

例如,使用RDF4J的Rio解析器,您可以创建一个简单的SubjectFilter类,以检查是否具有所需主题的任何三元组:

public class SubjectFilter extends RDFHandlerWrapper {

    @Override
    public void handleStatement(Statement st) throws RDFHandlerException {
       // only write the statement if it has a subject we want
       if (myListOfSubjects.contains(statement.getSubject()) {
          super.handleStatement(st);
       } 
    }
}

然后将解析器连接到编写器,该编写器吐出经过过滤的内容,具体如下:

RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE);
RDFWriter rdfWriter = Rio.createWriter(RDFFormat.TURTLE,
               new FileOutputStream("/path/to/example-output.ttl"));

// link our parser to our writer, wrapping the writer in our subject filter
rdfParser.setRDFHandler(new SubjectFilter(rdfWriter));

// start processing
rdfParser.parse(new FileInputStream("/path/to/input-file.ttl"), ""); 

有关如何使用RDF4J和Rio解析器的更多详细信息,请参见documentation

顺便说一句:虽然这可能比用grep和awk之类的命令行魔术来做更多的工作,但好处是它在语义上很健壮:您可以将数据的哪一部分解释为三元组的主题。 理解 RDF的处理器,而不是通过正则表达式进行有根据的猜测(“可能是每行的第一个URL”),如果输入文件使用略有不同的语法变体,则可能会中断。

(披露:我是RDF4J开发团队的成员)