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

У меня есть файл, содержащий тройной RDF (субъект-предикат-объект) в синтаксисе черепахи (.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 прочитать содержимое второго файла в массиве и использовать метод «содержать», чтобы проверить, соответствуют ли предметы каждой тройки первого файла какой-либо строке во втором файле, однако это слишком медленно, поскольку файлы очень большой. Как я мог получить это?

Большое спасибо за помощь


person Furabio JZ4    schedule 14.04.2019    source источник


Ответы (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);
       } 
    }
}

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

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, преимущество в том, что это семантически устойчиво: вы оставляете интерпретацию того, какой бит ваших данных является объектом триплета процессору, который < em>понимает RDF, а не делает обоснованные предположения с помощью регулярных выражений («вероятно, это первый URL в каждой строке»), что может привести к поломке в тех случаях, когда во входном файле используется несколько иной вариант синтаксиса.

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

person Jeen Broekstra    schedule 15.04.2019