阅读 RDF 不起作用

Reading RDF does not work

我正在尝试加载一个 foaf 文件:

import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;

public class Testbed {
    public static void main(String[] args) {
        Model model = ModelFactory.createDefaultModel();

        try {
                model.read("http://www.csail.mit.edu/~lkagal/foaf", "RDF/XML"); 
        }
        catch(Exception ex) {
            System.out.println(ex.toString());
        }
    }
}

我遇到以下异常:

org.apache.jena.riot.RiotException: [line: 1, col: 50] White spaces are required between publicId and systemId.

我不明白这个异常是什么意思。我该如何解决它。我是否使用了错误的格式(看起来不像 "TURTLE" 或任何其他格式)?

我的环境(Windows 10 x64,apache-jena-3.1.1):

java version "1.8.0_112" Java(TM) SE Runtime Environment (build 1.8.0_112-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode

URL http://www.csail.mit.edu/~lkagal/foaf 实际上是重定向到 http://people.csail.mit.edu/lkagal/foaf。重定向的存在是错误的原因。

问题已在 Jena 的开发分支中报告并修复(错误 [JENA-1263])。

分析

Apache Jena uses Apache HttpClient 用于连接处理。特别是,Jena 3.1.0 使用 HttpClient 4.2.6,在 Jena 3.1.1.

中更新为 HttpClient 4.5.2

正如 指出的那样,使用 Jena 3.1.0 不存在该问题,原因是它创建了一个默认支持各种功能的连接,包括自动跟随重定向(它使用 new SystemDefaultHttpClient()).

相反,随着 HttpClient 的更新,在 Jena 3.1.1 中修改了代码以创建更小的连接类型,无法遵循重定向(它使用 HttpClients.createMinimal()).

发生的事情是,它没有到达您的 foaf 文件,而是检索了重定向消息:

name="[xml]",ch=DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://people.csail.mit.edu/lkagal/foaf">here</a>.</p>
<hr>
<address>Apache/2.2.16 (Debian) Server at www.csail.mit.edu Port 80</address>
</body></html>

然后尝试用 Apache Xerces 解析它,这实际上是抛出异常的那个(你可以通过使用 ex.printStackTrace() 而不是 System.out.println(ex.toString()) 来看到):

...
at org.apache.xerces.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:282)
at org.apache.xerces.impl.XMLScanner.reportFatalError(XMLScanner.java:1467)
at org.apache.xerces.impl.XMLScanner.scanExternalID(XMLScanner.java:1001)
...

解决方案

  • 直接使用URL、http://people.csail.mit.edu/lkagal/foaf
  • 使用以前的版本Jena
  • 使用Jena
  • 的开发分支
  • Jena 提供您自己的 "redirect capable" 连接,以代替默认连接;您可以在使用 model.read 之前调用方法 HttpOp.setDefaultHttpClient,例如:

    HttpOp.setDefaultHttpClient(HttpClientBuilder.create().build());