如何配置RDF4J Rio编写器来编写具有特殊字符的IRI



我想用rdf/turtle格式编写一个rdf4j.model.Model。该模型应包含字符为{}的IRI。

当我尝试用rdf4j.rio.Rio编写RDF模型时,{}字符被写成%7B%7D。有没有办法克服这个问题?例如,创建具有路径和查询变量的rdf4j.model.IRI,或者配置写入程序以保留{}字符?

我正在使用org.eclipse.rdf4j:rdf4j-runtime:3.6.2

示例片段:

import org.eclipse.rdf4j.model.BNode;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Model;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.model.util.ModelBuilder;
import org.eclipse.rdf4j.rio.*;
import org.eclipse.rdf4j.rio.helpers.BasicWriterSettings;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ExamplePathVariable {
private final static Logger LOG = Logger.getLogger(ExamplePathVariable.class.getCanonicalName());
public static void main(String[] args) {
SimpleValueFactory rdf = SimpleValueFactory.getInstance();
ModelBuilder modelBuilder = new ModelBuilder();
BNode subject = rdf.createBNode();
IRI predicate = rdf.createIRI("http://example.org/onto#hasURI");
// IRI with special characters !
IRI object = rdf.createIRI("http://example.org/{token}");
modelBuilder.add(subject, predicate, object);
String turtleStr = writeToString(RDFFormat.TURTLE, modelBuilder.build());
LOG.log(Level.INFO, turtleStr);
}
static String writeToString(RDFFormat format, Model model) {
OutputStream out = new ByteArrayOutputStream();
try {
Rio.write(model, out, format,
new WriterConfig().set(BasicWriterSettings.INLINE_BLANK_NODES, true));
} finally {
try {
out.close();
} catch (IOException e) {
LOG.log(Level.WARNING, e.getMessage());
}
}
return out.toString();
}
}

这就是我得到的:

INFO: 
[] <http://example.org/onto#hasURI> <http://example.org/%7Btoken%7D> .

没有简单的方法可以实现您想要的,因为这会导致Turtle中的URI表示在语法上无效。

字符"{"one_answers"}",即使它们实际上不是URI中的保留字符,也不允许以未编码的形式存在于URI中(请参阅https://datatracker.ietf.org/doc/html/rfc3987)。合法序列化它们的唯一方法是对它们进行百分比编码。

顺便说一句,这段代码的唯一原因是:

IRI object = rdf.createIRI("http://example.org/{token}");

成功之处在于您正在使用的SimpleValueFactory不进行字符验证(出于性能原因(。如果您使用推荐的方法(自RDF4J 3.5起(使用Values静态工厂:

IRI object = Values.iri("http://example.org/{token}");

您会立即得到一个验证错误。

如果你想输入一个字符串,而你事先不知道它是否会包含任何无效字符,并且想尽最大努力将其转换为合法的URI,你可以使用ParsedIRI.create:

IRI object = Values.iri(ParsedIRI.create("http://example.org/{token}").toString());

最新更新