1. Jena配置
  2. RDF例子
    1. 创建RDF模型
    2. 查询RDF模型
    3. 输出xml
    4. 读入xml
  3. 参考

Jena是一个用于构建语义网(Semantic Web)Linked Data应用的Java开源框架,可处理RDF数据,详见:https://jena.apache.org/

Jena配置

https://jena.apache.org/download/index.cgi 下载Jena,目前是apache-jena-3.0.1.zip

环境要求:Java8

在Eclipse中使用:右键点击项目 -> 属性/Properties -> Java创建路径/Java Build Path -> 库/Libraries -> 添加外部文件/Add Extenal JARs -> 添加解压apache-jena-3.0.1.zip后的lib目录下的jar文件。

RDF例子

参考https://jena.apache.org/tutorials/rdf_api.html

资源描述框架(Resource Description Framework,RDF)是描述资源的一项标准(W3C推荐标准)。

使用关于vcard的RDF:https://www.w3.org/TR/vcard-rdf/

一个vcard在RDF中如图:

资源JohnSmith在图中用椭圆表示,并被一个统一资源定位符(URI)所标识,在本例中是http://.../JohnSmith 。

创建RDF模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.vocabulary.VCARD;

public class Tutorial extends Object {

public static void main(String args[]) {
// some definitions
String personURI = "http://somewhere/JohnSmith";
String givenName = "John";
String familyName = "Smith";
String fullName = givenName + " " + familyName;

// create an empty model
Model model = ModelFactory.createDefaultModel();

// create the resource
// and add the properties cascading style
Resource johnSmith = model
.createResource(personURI)
.addProperty(VCARD.FN, fullName)
.addProperty(
VCARD.N,
model.createResource()
.addProperty(VCARD.Given, givenName)
.addProperty(VCARD.Family, familyName));

}
}

查询RDF模型

最通用的查询方法是Model.listStatements(Resource s, Property p, RDFNode o)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import org.apache.jena.rdf.model.Property;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.rdf.model.StmtIterator;

// select all the resources with a VCARD.FN property
// whose value ends with "Smith"
StmtIterator iter = model.listStatements(new SimpleSelector(null,
VCARD.FN, (RDFNode) null) {
@Override
public boolean selects(Statement s) {
return s.getString().endsWith("Smith");
}
});

// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
Statement stmt = iter.nextStatement(); // get next statement
Resource subject = stmt.getSubject(); // get the subject
Property predicate = stmt.getPredicate(); // get the predicate
RDFNode object = stmt.getObject(); // get the object

System.out.print(subject.toString());
System.out.print(" " + predicate.toString() + " ");
if (object instanceof Resource) {
System.out.print(object.toString());
} else {
// object is a literal
System.out.print(" \"" + object.toString() + "\"");
}
System.out.println(" .");
}

查询特定的资源时,可以使用model.getResource(String URI)Model.listSubjectsWithProperty(Property p, RDFNode o)

1
2
3
4
5
6
7
// retrieve the John Smith vcard resource from the model
Resource vcard = model.getResource(johnSmithURI);
// retrieve the value of the N property
Resource name = (Resource) vcard.getRequiredProperty(VCARD.N)
.getObject();
// retrieve the given name property
String fullName = vcard.getRequiredProperty(VCARD.FN).getString();
1
2
3
4
import org.apache.jena.rdf.model.ResIterator;

// select all the resources with a VCARD.FN property
ResIterator iter = model.listResourcesWithProperty(VCARD.FN);

输出xml

使用model.write(System.out);即可输出xml到标准输出流中,使用不同的OutputStream参数或把标准输出流指向文件流即可输出xml文件。

1
2
3
4
5
6
7
8
9
10
11
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">
<rdf:Description rdf:about="http://somewhere/JohnSmith">
<vcard:N rdf:parseType="Resource">
<vcard:Family>Smith</vcard:Family>
<vcard:Given>John</vcard:Given>
</vcard:N>
<vcard:FN>John Smith</vcard:FN>
</rdf:Description>
</rdf:RDF>

此外也可以输出RDF/XML-ABBREVN-TRIPLE形式的模型:

1
2
model.write(System.out, "RDF/XML-ABBREV");
model.write(System.out, "N-TRIPLE");
1
2
3
4
5
6
7
8
9
10
11
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">
<rdf:Description rdf:about="http://somewhere/JohnSmith">
<vcard:N rdf:parseType="Resource">
<vcard:Family>Smith</vcard:Family>
<vcard:Given>John</vcard:Given>
</vcard:N>
<vcard:FN>John Smith</vcard:FN>
</rdf:Description>
</rdf:RDF>
1
2
3
4
<http://somewhere/JohnSmith> <http://www.w3.org/2001/vcard-rdf/3.0#N> _:BX2D1e94da86X3A153bb598690X3AX2D7fff .
<http://somewhere/JohnSmith> <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" .
_:BX2D1e94da86X3A153bb598690X3AX2D7fff <http://www.w3.org/2001/vcard-rdf/3.0#Family> "Smith" .
_:BX2D1e94da86X3A153bb598690X3AX2D7fff <http://www.w3.org/2001/vcard-rdf/3.0#Given> "John" .

读入xml

使用model.read(System.in, "");即从标准输入流中读入rdf模型,使用不同的InputStream参数或把标准输入流指向文件流即可读入xml文件。

1
2
3
4
5
6
7
InputStream in = (InputStream) FileManager.get().open( inputFileName );
if (in == null) {
throw new IllegalArgumentException( "File: " + inputFileName + " not found");
}

// read the RDF/XML file
model.read(in, "");

参考

https://jena.apache.org/

https://github.com/apache/jena/blob/master/jena-core/src-examples/jena/examples/

http://domdong.blogspot.sg/2013/04/an-introduction-to-rdf-and-jena-rdf-api.html

http://www.ibm.com/developerworks/cn/java/j-jena/