我正在尝试加载一个 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
的开发分支中报告并修复(bug [JENA-1263])。
分析
Apache Jena使用 Apache HttpClient用于连接处理。特别是,Jena 3.1.0
使用 HttpClient 4.2.6
,在 Jena 3.1.1< 中更新为
.HttpClient 4.5.2
/
作为@potame指出,使用 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
提供您自己的“支持重定向”连接,以代替默认连接;您可以在使用model.read
之前调用方法HttpOp.setDefaultHttpClient
,例如:HttpOp.setDefaultHttpClient(HttpClientBuilder.create().build());
关于java - 阅读 RDF 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41124704/