#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)