使用 RDF4J 在加载和写入 TTL 文件时保留前缀
Keep prefixes in loading and writing TTL file with RDF4J
我需要加载一个 Turtle TTL 文件,添加一些三元组,然后再次保存。
原始 TTL 文件有一个很大的 header 包含一些命名空间的前缀。
@prefix biro: <http://purl.org/spar/biro/> .
@prefix c4o: <http://purl.org/spar/c4o/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix deo: <http://purl.org/spar/deo/> .
@prefix doco: <http://purl.org/spar/doco/> .
...
加载文件并添加三元组后,保存的 TTL 将不包含前缀,除非我手动指定它们,一一指定。有没有办法让命名空间已经存在于加载的文件中?
这是我的 Java 代码:
// Load input TTL file
InputStream stream = new FileInputStream(ttlFile);
RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE);
Model model = new LinkedHashModel();
rdfParser.setRDFHandler(new StatementCollector(model));
rdfParser.parse(stream);
stream.close();
// Code to add triples here
model.add(...);
// Save the new TTL file
FileOutputStream out = new FileOutputStream(ttlOutputFile);
RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out);
writer.startRDF();
// Here I can add the prefixes manually
// writer.handleNamespace("dcterms", DCTERMS.NAMESPACE);
for (Statement st : model) {
writer.handleStatement(st);
}
writer.endRDF();
问题是您用于写入文件的代码明确地只写入语句本身,而不是存储在您的 model
对象中的名称空间。
您可以通过添加如下内容来修复它:
model.getNamespaces().forEach(ns -> writer.handleNamespace(ns.getPrefix(), ns.getName()));
但是,更一般地说,写入文件的代码比需要的更复杂。将 model
对象写入文件的一种更简单的方法是这样的:
// Save the new TTL file
FileOutputStream out = new FileOutputStream(ttlOutputFile);
Rio.write(model, out, RDFFormat.TURTLE);
或者如果您更喜欢使用 RDFWriter
对象(这样您就可以调整配置):
RDFWriter writer = Rio.createWriter(out, RDFFormat.TURTLE);
//... tweak writer config
Rio.write(model, writer);
这两个都是更短、更简单的代码,它们还为您处理命名空间。
同样,读取文件也可以更方便的完成:
// Load input TTL file
InputStream stream = new FileInputStream(ttlFile);
Model model = Rio.parse(stream, RDFFormat.TURTLE);
我需要加载一个 Turtle TTL 文件,添加一些三元组,然后再次保存。 原始 TTL 文件有一个很大的 header 包含一些命名空间的前缀。
@prefix biro: <http://purl.org/spar/biro/> .
@prefix c4o: <http://purl.org/spar/c4o/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix deo: <http://purl.org/spar/deo/> .
@prefix doco: <http://purl.org/spar/doco/> .
...
加载文件并添加三元组后,保存的 TTL 将不包含前缀,除非我手动指定它们,一一指定。有没有办法让命名空间已经存在于加载的文件中?
这是我的 Java 代码:
// Load input TTL file
InputStream stream = new FileInputStream(ttlFile);
RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE);
Model model = new LinkedHashModel();
rdfParser.setRDFHandler(new StatementCollector(model));
rdfParser.parse(stream);
stream.close();
// Code to add triples here
model.add(...);
// Save the new TTL file
FileOutputStream out = new FileOutputStream(ttlOutputFile);
RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out);
writer.startRDF();
// Here I can add the prefixes manually
// writer.handleNamespace("dcterms", DCTERMS.NAMESPACE);
for (Statement st : model) {
writer.handleStatement(st);
}
writer.endRDF();
问题是您用于写入文件的代码明确地只写入语句本身,而不是存储在您的 model
对象中的名称空间。
您可以通过添加如下内容来修复它:
model.getNamespaces().forEach(ns -> writer.handleNamespace(ns.getPrefix(), ns.getName()));
但是,更一般地说,写入文件的代码比需要的更复杂。将 model
对象写入文件的一种更简单的方法是这样的:
// Save the new TTL file
FileOutputStream out = new FileOutputStream(ttlOutputFile);
Rio.write(model, out, RDFFormat.TURTLE);
或者如果您更喜欢使用 RDFWriter
对象(这样您就可以调整配置):
RDFWriter writer = Rio.createWriter(out, RDFFormat.TURTLE);
//... tweak writer config
Rio.write(model, writer);
这两个都是更短、更简单的代码,它们还为您处理命名空间。
同样,读取文件也可以更方便的完成:
// Load input TTL file
InputStream stream = new FileInputStream(ttlFile);
Model model = Rio.parse(stream, RDFFormat.TURTLE);