org.eclipse.rdf4j.rio.RDFWriter,编写文档时如何设置基础命名空间

问题描述 投票:0回答:1

我正在使用 rdf4j 库导出 xml 文件。 我使用 org.eclipse.rdf4j.rio.RDFWriter 将其保存在文件中,我需要定义基本命名空间。所以我希望有类似的东西:

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xml:base="http://exmaple.org/">
<rdf:Description rdf:about=foo>
<rdf:type rdf:resource= FOO>
...

我知道我可以使用handleNamespace()设置命名空间。但我不知道如何使用它来设置基本命名空间:我尝试过:

ModelBuilder builder = new ModelBuilder();
ValueFactory vf = SimpleValueFactory.getInstance();
builder.add(vf.createIRI("base:foo"), RDFS.ISDEFINEDBY, vf.createIRI("base:FOO");
Model model = builder.build();
RDFWriter writer = Rio.createWriter(RDFFormat.RDFXML, someOutputStream);
try {
  writer.startRDF();
  writer.handleNamespace("base", "http://exmaple.org/");
      for (Statement st: model) {
  writer.handleStatement(st);
  }
  writer.endRDF();
...

但这并没有给我我所期望的:

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:base="http://exmaple.org/">
<rdf:Description rdf:about=base:foo>
<rdf:type rdf:resource= base:FOO>

有什么想法吗?

java xml namespaces rdf4j
1个回答
0
投票

命名空间与基本 URI 不同,并且不存在“基本命名空间”这样的东西。命名空间是 URI 的缩写机制,您可以在其中定义一个前缀,用短字符串替换完整 URI 的第一部分,以便在 RDF 数据中可以用“前缀名称”(取决于特定的 RDF 语法)表示 URI到底是什么样子的)。

另一方面,基础 URI 是一种通用解析器/编写器机制,允许解析数据中的“相对 URI”。某些语法格式(如 XML)允许在文档本身中定义基本 URI,而其他格式则不允许,但它们的用途与命名空间不同。

举个例子,这个 XML 片段:

<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns:base="http://example.org/"> <rdf:Description rdf:about="foo"> ....

是合法的 RDF,尽管 RDF 规范要求
rdf:about
属性(

subject

)的值是完整的 URI。它合法的原因是定义了一个基本 URI,字符串 
foo 可以解析为相对 URI。解析后的完整 URI 将为 http://example.org/foo
。请注意,这与命名空间“无关”。
您的代码中发生的情况是您根本没有使用基本 URI。在第一部分中,您将使用 
ModelBuilder 在内存中定义 RDF 模型。您正在添加字符串 base:foo

作为主题。

ModelBuilder

 将此解释为完整 URI,因为模型构建器中没有定义以 
base
 作为前缀的命名空间。
将该模型写入 XML 文件并不会改变这一点,无论您将什么定义为基本 URI 或命名空间
在写入时
:您正在导出将 
base:foo

作为完整 URI 的 RDF 模型,因此这就是您将得到的结果在你的输出中。

要获得所需的内容,您需要确保您的 Model

 对象具有完整的 URI,并且不要尝试向编写器添加命名空间,而是在 
创建

编写器时设置其基本 URI。

        var model = new ModelBuilder().add("http://example.org/foo", RDFS.ISDEFINEDBY, "http://example.org/FOO").build();
        var writer = Rio.createWriter(RDFFormat.RDFXML, System.out, "http://example.org/");

        writer.startRDF();
        for (Statement st : model) {
            writer.handleStatement(st);
        }
        writer.endRDF();
...或更简洁地说:

var model = new ModelBuilder().add("http://example.org/foo", RDFS.ISDEFINEDBY, "http://example.org/FOO").build(); Rio.write(model, System.out, "http://example.org/", RDFFormat.RDFXML);
如果您不喜欢每次创建模型时都必须编写完整的 URI,那么命名空间就可以派上用场,例如:

var model = new ModelBuilder().setNamespace("ex", "http://example.org/") .add("ex:foo", RDFS.ISDEFINEDBY, "ex:FOO").build();
    

© www.soinside.com 2019 - 2024. All rights reserved.