Jena的一個例子

 

JENA中有一個最底層的接口:RDFNode,它代表RDF這張巨大圖中的節點,這個節點可以是一個資源,可以是一個字符竄或者數字。因此它對應與2個子接口:
interface Literal extends RDFNode
interface Resource extends RDFNode
Literal接口代表了一些原始類型節點,比如:32位整型、布爾型等等。
Resource接口還可以繼續衍生出2個重要的接口:
interface Container extends Resource
interface Property extends Resource
Container接口就對應了RDF的容器表達能力,裏面有bag,seq,alt
Property接口就是所謂的資源屬性了

在RDF的世界中,其實描述資源只有一種方式,那就是三元組,包括:主體(subject),謂詞(predicate),客體(object)。主體和客體就是圖中的2個節點,謂詞就是一條邊。這三元組在JENA中用Statement接口來描述,該接口中有下面3個方法:
public Resource getSubject();
public Property getPredicate();
public RDFNode getObject();

我們可以發現,主體一定是一種資源,不可能是一個Literal原始類型,因此主體必定屬於Resource接口實現,但是客體可以是原始類型,比如:人有2條腿。爲主體;爲謂詞;2爲客體。

用一個例子來鞏固下:

  1. <?xml version="1.0"?>
  2. <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  3. xmlns:s="http://example.org/students/vocab#">
  4. <rdf:Description rdf:about="http://example.org/courses/6.001">
  5.    <s:students>
  6. <rdf:Bag>
  7.    <rdf:li rdf:resource="http://example.org/students/Amy"/>
  8.    <rdf:li rdf:resource="http://example.org/students/Mohamed"/>
  9.    <rdf:li rdf:resource="http://example.org/students/Johann"/>
  10.    <rdf:li rdf:resource="http://example.org/students/Maria"/>
  11.    <rdf:li rdf:resource="http://example.org/students/Phuong"/>
  12. </rdf:Bag>
  13.    </s:students>
  14. </rdf:Description>
  15. </rdf:RDF>

用JENA來解析這個例子:

  1. Model model = ModelFactory.createDefaultModel();
  2. model.read(new FileInputStream("student.rdf"), null);
  3. StmtIterator it = model.listStatements();
  4. while(it.hasNext())
  5. {
  6. System.out.println(it.next());
  7. }

打印的結果如下:
[http://example.org/courses/6.001, http://example.org/students/vocab#students, -23ba78ea:125e9da42c8:-8000]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_5, http://example.org/students/Phuong]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_4, http://example.org/students/Maria]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_3, http://example.org/students/Johann]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_2, http://example.org/students/Mohamed]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#_1, http://example.org/students/Amy]
[-23ba78ea:125e9da42c8:-8000, http://www.w3.org/1999/02/22-rdf-syntax-ns#type, http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag]

 

 

在RDF入門的例子中,有這樣一幅圖:

空節點,雖然它也是一個資源,但這個資源沒有必要標上資源描述符,因爲它可能只在應用程序局部使用,作爲推理機的一個橋樑等等作用,換句說,這個資源別人沒有必要去引用。這樣的節點,我們稱之爲空節點:

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource blankNode = model.createResource(new AnonId("tempNode"));
  3. Property city = model.createProperty("http://www.crabobe.com/city");
  4. Property street = model.createProperty("http://www.crabobe.com/street");
  5. blankNode.addProperty(city, "深圳");
  6. blankNode.addProperty(street, "龍崗");
  7. Resource crab = model.createResource("http://www.crabobe.com/crab");
  8. Property address = model.createProperty("http://www.crabobe.com/address");
  9. crab.addProperty(address, blankNode);
  10. model.write(System.out);

注意,包含中文的源碼文件必須是UTF-8的,運行結果如下:

  1. <rdf:RDF
  2. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  3. xmlns:j.0="http://www.crabobe.com/" >
  4. <rdf:Description rdf:about="http://www.crabobe.com/crab">
  5. <j.0:address rdf:nodeID="A0"/>
  6. </rdf:Description>
  7. <rdf:Description rdf:nodeID="A0">
  8. <j.0:street>龍崗</j.0:street>
  9. <j.0:city>深圳</j.0:city>
  10. </rdf:Description>
  11. </rdf:RDF>

RDF作爲資源描述框架,有2件事情是它的本職工作,第一,描述資源的唯一性,只有統一了,各種應用才能達成共識,好比秦始皇那會兒一樣。第二,要把資源表述得有條有理。下面,拿出代碼來解釋。

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource crab = model.createResource("http://www.crabobe.com/crab");
  3. model.write(System.out);

上面,我們用jena建立了crab這樣一個資源,當然,crab只是java內存中的一個變量名而已,它真是的標識符號是http://www.crabobe.com/crab,也即,在這個世界上,這個資源是唯一存在的。

我們繼續添加一個資源

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource crab = model.createResource("http://www.crabobe.com/crab");
  3. Property numerOfLeg = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  4. model.write(System.out);

這裏我們添加了一個資源numerOfLeg,有人問,它是一個屬性(Property)吧?沒錯,但在RDF中,屬性也是一種資源,在JENA中,Property是Resource的子接口。既然它是一種資源,那必定得有唯一的標識符,這個標識符就是http://www.crabobe.com/crab#numerOfLeg

接着我們用numerOfLeg這個屬性來描述crab

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource crab = model.createResource("http://www.crabobe.com/crab");
  3. Property numerOfLeg = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  4. crab.addProperty(numerOfLeg, "8");
  5. model.write(System.out);

運行的結果:

  1. <rdf:RDF
  2. xmlns:j.0="http://www.crabobe.com/crab#"
  3. xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
  4. <rdf:Description rdf:about="http://www.crabobe.com/crab">
  5. <j.0:numerOfLeg>8</j.0:numerOfLeg>
  6. </rdf:Description>
  7. </rdf:RDF>

關於這個結果,雖然很簡單,但是裏面有個細節需要我們去關注!!同樣是資源描述符,資源的描述符和屬性的描述符是不一樣的。區別就體現在,資源的描述符僅僅是作爲rdf:Description標籤的一個屬性,而屬性的描述符卻要被用來作爲XML標籤。在這點上來看,屬性的資源描述符一定要帶有相對路徑,假如我們這樣寫:
model.createProperty(”http://www.crabobe.com”);
那麼這個屬性標籤的命名空間就沒有了,如果命名空間標示爲http://www.crabobe.com,那它自己的名稱呢?所以,jena會報錯。
所以,我們的寫法可以是這樣:
http://www.crabobe.com/crab
那麼http://www.crabobe.com/就是命名空間,crab就是標籤名稱
也可以像例子都那樣寫:
http://www.crabobe.com/crab#numerOfLeg
那麼命名空間就是http://www.crabobe.com/crab#,被jena簡寫成j.0,名稱就是numerOfLeg。

現在,我們來驗證資源的唯一性:

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource crab = model.createResource("http://www.crabobe.com");
  3. Resource crab1 = model.createResource("http://www.crabobe.com");
  4. Property numerOfLeg = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  5. Property numerOfLeg1 = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  6. crab.addProperty(numerOfLeg, "8");
  7. crab1.addProperty(numerOfLeg1, "8");
  8. model.write(System.out);

這裏,我們人爲寫出2個對象,但是資源描述符寫成一樣,這2個對象分別有各自屬性,按照唯一性,那麼內存中即使對象再是多,在RDF規範中,只會認資源描述符,只要資源描述符是一樣的,那麼就視爲一個資源。運行的結果,符合我們的推理。

如果我們改一改:

  1. Model model = ModelFactory.createDefaultModel();
  2. Resource crab = model.createResource("http://www.crabobe.com");
  3. Resource crab1 = model.createResource("http://www.crabobe.com");
  4. Property numerOfLeg = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  5. Property numerOfLeg1 = model.createProperty("http://www.crabobe.com/crab#numerOfLeg");
  6. crab.addProperty(numerOfLeg, "8");
  7. crab1.addProperty(numerOfLeg1, "10");
  8. model.write(System.out);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章