Как удалить строки с определенными темами из файла RDF?

#file #replace #rdf #dbpedia

#файл #заменить #rdf #dbpedia

Вопрос:

У меня есть файл, содержащий тройной RDF (субъект-предикат-объект) в синтаксисе turtle (.ttl), и у меня есть другой файл, в котором у меня есть только некоторые объекты.

Например:

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

В Java вы можете использовать библиотеку RDF для чтения / записи в потоковом режиме и выполнять некоторую базовую фильтрацию.

Например, используя анализатор Rio от RDF4J, вы можете создать простой 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);
       } 
    }
}
 

А затем подключите анализатор к writer, который выдает отфильтрованное содержимое, что-то вроде этих строк:

 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, см. Документацию.

В качестве отступления: хотя это, возможно, больше работы, чем выполнение какой-либо магии командной строки с такими вещами, как grep и awk, преимущество заключается в том, что это семантически надежно: вы оставляете интерпретацию того, какой бит ваших данных является объектом triple, процессору, который понимает RDF, вместо того, чтобы делать обоснованные предположения с помощьюрегулярное выражение («вероятно, это первый URL-адрес в каждой строке»), которое может прерываться в тех случаях, когда во входном файле используется немного другой синтаксический вариант.

(раскрытие информации: я в команде разработчиков RDF4J)