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

How to delete lines with specific subjects from an RDF file?

我有一个文件包含 turtle 语法 (.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 读取数组列表中第二个文件的内容并使用 "contain" 方法检查第一个文件的每个三元组的主题是否与第二个文件中的任何行匹配文件,但是它太慢了,因为文件非常大。我怎么能得到这个?

非常感谢您的帮助

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

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

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 的处理器,而不是通过正则表达式 ("it's probably the first URL on each line") 进行有根据的猜测,这可能会在输入文件使用稍微不同的语法变体的情况下中断。

(披露:我在 RDF4J 开发团队)