日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql jena rdf_RDF和Jena RDF API简介

發布時間:2023/12/14 数据库 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql jena rdf_RDF和Jena RDF API简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是官方文章《An Introduction to RDF and the Jena RDF API》的譯文。原文是在刺猬的溫馴這里看到的。其中的圖片沒法顯示了,還有一段丟失了。于是我在此也補充翻譯一下。^_^

前言

本文是一篇對W3C的資源描述框架(RDF)和 Jena(一個Java的RDF API)的教程性介紹. 本文是為那些不熟悉RDF的, 以及那些通過建立原形可以達到最好學習效果的, 或是因為其他原因希望能快速操作Jena的程序員而寫的. 我們假設讀者在閱讀本文前已具有一定的XML和Java知識.

如果讀者在沒有理解RDF數據模型的基礎上就迅速進入操作階段,往往會導致失敗和失望. 然而,如果光學習數據模型又是十分枯燥乏味的, 并常常會導致曲折的形而上學的難題. 更好的學習辦法是在理解數據模型的同時練習操作它. 可以先學習一點數據模型再動手試一試.然后在學習一點再試一試. 這樣一來就能達到理論實踐相結合的效果.數據模型本身十分簡單,所以學習過程不會太長.

RDF具有XML的語法, 所以許多熟悉XML的人就會認為以XML語法的形式來思考RDF. 然而, 這是不對的. RDF應該以它數據模型的形式來被理解. RDF數據可是用XML來表示, 但是理解數據模型的重要性更在理解此語法重要性之上.

Jena API的一個運行例子, 包括本教程中所有例子的工作源代碼都可以在http://www.hpl.hp.com/semweb/下載.

________________________________________

目錄

1. 導言

2. 陳述Statements

3. RDF寫操作

4. RDF讀操作

5. Jena RDF 包

6. 操縱模型

7. 查詢模型

8. 對模型的操作

9. 容器Containers

10. 關于Literals和數據類型的更多探討

11. 術語表

________________________________________

導言

資源描述框架是(RDF)是描述資源的一項標準(在技術上是W3C的推薦標準). 什么是資源? 這實在是一個很難回答的問題, 其精確的定義目前尚在爭論中. 出于我們的目的, 我們可以把資源想象成任何我們可以確定識別的東西. 在本教程中,讀者你本身就是一個資源, 而你的主頁也是一個資源, 數字1和故事中巨大的白鯨都是資源.

在本教程中, 我們的例子會圍繞人們展開. 假設人們會使用VCARDS, 而VCARD將由RDF表示機制來描述. 我們最好把RDF考慮成由結點和箭頭的形式構成的圖. 一個簡單的vcard在RDF中可能看起來是這樣的:

資源John Smith在圖中用橢圓表示, 并被一個統一資源定位符(URI) 所標識, 在本例中是"http://.../JohnSmith"). 如果你想要通過你的瀏覽器來訪問這個資源的話,你很有可能會失敗. 四月的愚人節笑話并不經得起考驗, 相反如果你的瀏覽器把John Smith傳遞到你的桌面的話, 你才該感到驚訝. 如果你并不熟悉URI's的話, 你可以把它們想象成簡單的陌生名字.

資源擁有屬性(property). 在這些例子中, 我們對John Smith名片上出現的那些屬性很感興趣.圖1只顯示了一個屬性, John Smith的全名. 屬性是由標有屬性名的箭頭表示的. 屬性的名字也是一個URI, 但是由于URI十分冗長笨重, 所以圖中將它顯示為XML qname的形式. 在':'之前的部分稱為命名空間前綴并表示了一個命名空間. 在':'之后的部分稱為局部名, 并表示在命名空間中的一個名字. 在寫成RDF XML形式時, 屬性常常以qname的形式表示, 這是一個在圖形和文本中的簡單的縮寫方法. 然而, 嚴格地講, 屬性應該用URI來標識. 命名空間前綴:局部名的形式是一種命名空間連接局部名的URI縮寫. 當瀏覽器訪問時, 用并沒有強制屬性的URI必須指向一些具體的事物.

每個屬性都有一個值. 在此例中, 值為一個文本(literal), 我們現在可以把它看成一個字符串.文本在圖中顯示為長方形.

Jena是一個Java API, 我們可以用它來創建和操縱諸如上述例圖的RDF圖. Jena設有表示圖(graph), 資源(resource), 屬性和文本(literal)的對象類. 表示資源, 屬性和文本的接口分別稱為Resource, Property, 和Literal. 在Jena中, 一個圖(graph)被稱為一個模型并被Model接口所表示.

創建上述例圖或稱為上述模型的代碼很簡單:

// some definitions

static String personURI??? = "http://somewhere/JohnSmith";

static String fullName???? = "John Smith";

// create an empty Model

Model model = ModelFactory.createDefaultModel();

// create the resource

Resource johnSmith = model.createResource(personURI);

// add the property

johnSmith.addProperty(VCARD.FN, fullName);

這些代碼先定義了一些常量, 然后使用了ModelFactory類中的createDefaultMode()方法創建了一個空的基于內存存儲的模型(Model 或 model). Jena還包含了Model接口的其他實現方式. 例如, 使用關系數據庫的, 這些類型 Model接口也可以從ModelFactory中創建.

于是John Smith這個資源就被創建了, 并向其添加了一個屬性. 此屬性由一個"常" ("constant")類VCARD提供, 這個類保存了在VCARD模式(schema)中所有定義的表示對象. Jena也為其他一些著名的模式提供了常類的表示方法, 例如是RDF和RDF模式, Dublin 核心標準和DAML.

創建資源和添加屬性的代碼可以寫成更緊湊的層疊形式:

Resource johnSmith =

model.createResource(personURI)

.addProperty(VCARD.FN, fullName);

這個例子的工作代碼可以在Jena發布的材料的教程包中的Tutorial1中找到. 作為練習, 你自己可以獲得此代碼并修改其以創建一個簡單VCARD.

現在讓我們為vcard再增加一些更詳細的內容, 以便探索更多的RDF和Jena的特性.

在第一個例子里, 屬性值為一個文本. 然而RDF屬性也可以采用其他的資源作為其屬性值. 下面這個例子使用常用的RDF技術展示了如何表示John Smith名字的不同部分:

在這里我們增加了一個新的屬性, vcard:N, 來表示John Smith名字的結構. 這個模型有幾點有趣之處. 注意屬性vcard:N使用一個資源作為起屬性值. 同時注意代表復合名字的橢圓并沒有URI標識. 它被認為是一個空白結點(blank Node).

創建此例的Jena代碼也十分簡單. 首先是一些聲明和對空模型的創建.

// 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));

此例的工作代碼可以在Jena發布材料的教程包的Tutorial2中得到.

________________________________________

陳述

RDF模型中的每一個箭頭表示為一個陳述(statement). 每一個陳述聲明了關于某個資源的某個事實. 一個陳述有三部分組成.

主體, 也就是箭頭的出發的資源.

謂詞, 也就是標識箭頭的屬性.

客體, 也就是箭頭所指向的那個資源或文本.

一個陳述有時也叫做一個三元組的原因就是它由三部分組成.

一個RDF模型(譯者注: 指Jena中的接口Model)是由一組陳述所組成的. 在Tutorial2中, 每調用一次addProperty函數就會在模型中增加另一個陳述. (因為一個模型是由一組陳述組成的, 所以增加一個重復的陳述并不會產生任何意義.) Jena模型接口定義了一個listStatements()方法, 此方法會返回一個StmtIterator類型的變量. StmtItor是Java中Iterator的一個子類型, 這個StmtIterator變量重復迭代了該接口模型中的所有陳述. StmtIterator類型中有一個方法nextStatement(), 該方法會從iterator返回下一個陳述. (就和next()返回的一樣, 但是已將其映射為Statement類型). 接口Statement提供了訪問陳述中主體, 謂詞和客體的方法.

現在我們會用使用那個接口來擴展Tutorial2, 使起列出所有的創建的陳述并將它們打印出來. 此例完整的代碼可以在Tutorial3中找到.

// list the statements in the Model

StmtIterator iter = model.listStatements();

// 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(" .");

}

因為一個陳述的客體可以是一個資源也可以是一個文本. getObject()方法會返回一個類型為RDFNode的客體, RDFNode是Resource和Literal類共同的超類. 為了確定本例中的客體確切的類型, 代碼中使用 instanceof來確定其類型和相應的處理.

運行后, 此程序回產生與此相似的輸出:

http://somewhere/JohnSmith?http://www.w3.org/2001/vcard-rdf/3.0#N anon:14df86:ecc3dee17b:-7fff.

anon:14df86:ecc3dee17b:-7fff?http://www.w3.org/2001/vcard-rdf/3.0#Family? "Smith".

anon:14df86:ecc3dee17b:-7fff?http://www.w3.org/2001/vcard-rdf/3.0#Given? "John" .

http://somewhere/JohnSmith?http://www.w3.org/2001/vcard-rdf/3.0#FN? "John Smith".

現在你明白了為什么模型構建會更加清晰. 如果你仔細觀察, 就會發現上面每一行都由三個域組成, 這三個域分別代表了每一個陳述的主體, 謂詞和客體. 在此模型中有四個箭頭, 所以會有四個陳述. "anon:14df86:ecc3dee17b:-7fff"是有Jena產生的一個內部標識符, 它不是一個URI, 也不應該與URI混淆. 它只是Jena處理時使用的一個內部標號.

W3C的RDF核心工作小組定義了一個類似的表示符號稱為N-三元組(N-Triples). 這個名字表示會使用"三元組符號". 在下一節中我們會看到Jena有一個內置的N-三元組寫機制(writer).

________________________________________

寫RDF

Jena設有讀寫XML形式的RDF方法. 這些方法可以被用來將一個RDF模型保存到文件并在日后重新將其讀回.

Tutorial3創建了一個模型并將其以三元組的形式輸出. Tutorial4對Tutorial3做了修改, 使其將此模型以RDF XML的形式輸出到標準輸出流中. 這個代碼依然十分簡單: model.write可以帶一個OutputStream的參數.

// now write the model in XML form to a file

model.write(System.out);

應該有類似的輸出:

xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'

xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'

>

Jena有一個擴展的接口, 它允許新的為不同的RDF串行化語言設計的writer可以被輕易地插入. 以上的調用會激發一個標準的'啞'writer方法. Jena也包含了一個更加復雜的RDF/XML writer, 它可以被用攜帶另一個參數的write()方法所調用.

// now write the model in XML form to a file

model.write(System.out, "RDF/XML-ABBREV");

此writer, 也就是所謂的PrettyWriter, 利用RDF/XML縮寫語法把模型寫地更為緊湊. 它也能保存盡可能保留空白結點. 然而, 它并不合適來輸出大的模型. 因為它的性能不可能被人們所接受. 要輸出大的文件和保留空白結點, 可以用N-三元組的形式輸出:

// now write the model in XML form to a file

model.write(System.out, "N-TRIPLE");

這會產生類似于Tutorial3的輸出, 此輸出會遵循N-三元組的規格.

________________________________________

讀RDF

Tutorial 5 演示了如何將用RDF XML記錄的陳述讀入一個模型. 在此例中, 我們提供了一個小型RDF/XML形式的vcard的數據庫. 下面代碼會將其讀入和寫出. 注意: 如果要運行這個小程序, 應該把輸入文件放在你的classpath所指向的目錄或jar中.

// create an empty model

Model model = ModelFactory.createDefaultModel();

// use the class loader to find the input file

InputStream in = Tutorial05.class

.getClassLoader()

.getResourceAsStream(inputFileName);

if (in == null) {

throw new IllegalArgumentException(

"File: " + inputFileName + " not found");

}

// read the RDF/XML file

model.read(new InputStreamReader(in), "");

// write it to standard out

model.write(System.out);

read()方法中的第二個參數是一個URI, 它是被用來解決相對URI的. 因為在測試文件中沒有使用相對URI, 所以它允許被置為空值. 運行時, Tutorial5會產生類似如下的XML輸出

xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'

xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'

>

Smith

John

Sarah Jones

Becky Smith

________________________________________

前綴的操作

顯示前綴定義

在前面的章節中,我們可以看到在輸出XML中聲明了命名空間前綴vcard并且用這個前綴表示資源的URI縮寫。. 雖然RDF只使用URI的全長拼寫,而不是用它的縮寫形式。JENA卻使用前綴對應(映射)的方式,提供了在輸出時操作命名空間的寫法。興趣個簡單的例子。

Model m = ModelFactory.createDefaultModel();

String nsA = "http://somewhere/else#";

String nsB = "http://nowhere/else#";

Resource root = m.createResource( nsA + "root" );

Property P = m.createProperty( nsA + "P" );

Property Q = m.createProperty( nsB + "Q" );

Resource x = m.createResource( nsA + "x" );

Resource y = m.createResource( nsA + "y" );

Resource z = m.createResource( nsA + "z" );

m.add( root, P, x ).add( root, P, y ).add( y, Q, z );

System.out.println( "# -- no special prefixes defined" );

m.write( System.out );

System.out.println( "# -- nsA defined" );

m.setNsPrefix( "nsA", nsA );

m.write( System.out );

System.out.println( "# -- nsA and cat defined" );

m.setNsPrefix( "cat", nsB );

m.write( System.out );

從這段代碼運行的結果產生的三段RDF/XML,由于對應的前綴應對(映射)不同產生的RDF/XML也不同。默認的形式顯示在第一段,沒有任何前綴的形式(其實是系統內容的前綴,只是名字不好看)。

# -- no special prefixes defined

xmlns:j.0="http://nowhere/else#"

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:j.1="http://somewhere/else#" >

我們可以看到這個RDF命名空間是自動聲明的, 因數它是標簽和必需的。?屬性P和Q的使用也需要聲音XML命名空間, 但在這個例子中,沒有顯示的為模型給定它們的前綴。它們就選擇系統內部生成的(虛擬的)命名空間:?j.0?和?j.1。

方法setNsPrefix(String prefix, String URI)聲明了命名空間URI可以由prefix縮寫。JENA需要為它指定的這個prefix符合XML命名空間名字的規范,并且URI以非名稱字符結束。在輸出RDF/XML時,就會使用這些聲明的前綴來縮寫RDF/XML中的命名空間:

# -- nsA defined

xmlns:j.0="http://nowhere/else#"

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:nsA="http://somewhere/else#" >

這里可以看到nsA已經被用在屬性標簽中了,但是別的命名空間依然使用系統構建的。在JENA代碼中,只是用到這個方法,并不需要別的任何操作了:

# -- nsA and cat defined

xmlns:cat="http://nowhere/else#"

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:nsA="http://somewhere/else#" >

兩個前綴都使用到輸出中的URI縮寫中了,沒有使用任何的系統內部的前綴。

隱式定義前綴

除了調用setNsPrefix方法聲明前綴,其它JENA也會記住你在調用model.read()方法時讀入RDF使用的前綴。

把前面代碼生成的RDF/XML(有前綴的)粘貼到一個文件中,命名為file:/tmp/fragment.rdf。然后運行以下代碼。

Model m2 = ModelFactory.createDefaultModel();

m2.read( "file:/tmp/fragment.rdf" );

m2.write( System.out );

你將會看到從入庫的文件中使用的前綴也會出現在輸出文件各。所有的前綴都被聲明在了輸出文件上,除非那個前綴沒有被使用(聲明了但未使用)。如果有某些前綴不想用,不希望出現在輸出中,可以調用removeNsPrefix(String prefix)方法取消使用。

N-Triples沒有關于縮寫URI的方式,不需要在意前綴和在輸出上使用前綴。JENA也支持N3,沒有前綴縮寫,在輸入中記錄,在輸出中使用(這句不知道怎么翻譯了,原文:Since NTriples doesn't have any short way of writing URIs, it takes no notice of prefixes on output and doesn't provide any on input. The notation?N3, also supported by Jena, does have short prefixed names, and records them on input and uses them on output.)。

JENA還有對模型中的前綴映射有更進一步的操作,比如把現有的些映射關系封裝成一個java的Map對象(接口),或者一次性添加一批映射。關于PrefixMapping的更多細節請參閱相關文檔。

________________________________________

Jena RDF 包

Jena是一個為語義網應用設計的一個Java API. 對應用開發者而言, 主要可用的RDF包是com.hp.hpl.jena.rdf.model. 因為API是以接口的方式定義的, 所以應用代碼可以使用不同的實現機制而不用改變代碼本身. 這個包包含了可以表示模型, 資源, 屬性, 文本, 陳述和其他RDF關鍵概念的接口, 還有一個用來創建模型的ModelFactory. 所以如果要應用代碼與實現類保持獨立, 最好盡可能地使用接口, 而不要使用特定的實現類.

com.hp.hpl.jena.Tutorial包包含了本教程所有例子中使用到的工作源代碼.

com.hp.hpl.jena.impl這些包包含了許多執行時所常用的執行類. 比如, 它們定義了諸如ResourseImpl, PropertyImpl和LiteralImpl的類, 這些類可以被不同的應用直接使用也可以被繼承使用. 應用程序應該盡可能少地直接使用這些類. 例如, 與其使用ResouceImpl來創建一個新的實例, 更好的辦法是使用任何正在使用的模型的createResource方法來完成. 那樣的話, 如果模型的執行采用了一個優化的Resouce執行, 那么在這兩種類型中不需要有任何的轉換工作.

________________________________________

操縱模型

到目前為止, 本教程主要講述的是如何創建, 讀入和輸出RDF模型. 現在是時候要講述如何訪問模型中的信息.

如果有了一個資源的URI, 那么就可以用Model.getResource(String uri)來從模型獲取這個資源對象. 這個方法被定義來返回一個資源對象, 如果它確實存在于模型中, 否則的話就創建一個新的. 例如, 如何從模型中獲取Adam Smith資源, 這個模型是Tutorial5中從文件讀入的:

// retrieve the John Smith vcard resource from the model

Resource vcard = model.getResource(johnSmithURI);

Resouce接口定義了一系列用于訪問某個資源的屬性的方法. Resource.getProperty(Property p)方法訪問了該資源的屬性. 這個方法不允許通常的Java訪問的轉換, 因為所返回的對象是Statement, 而不是你所預計的Property. 返回整個陳述的好處是允許應用程序通過使用它的某個訪問方法來訪問該陳述的客體來訪問這個屬性值. 例如如何獲取作為vcard:N屬性值的資源:

// retrieve the value of the N property

Resource name = (Resource) vcard.getProperty(VCARD.N)

.getObject();

一般而言, 一個陳述的客體可以是一個資源或是一個文本. 所以此應用程序代碼知道這個值一定是個資源, 就將類型資源映射到返回的對象上. Jena的目標之一是提供會返回值為特定類型的方法, 這樣,應用程序就不必再做類型轉換工作, 也不必再編譯時做類型檢查工作. 以上的代碼片段也可以寫成更方便的形式:

// retrieve the value of the FN property

Resource name = vcard.getProperty(VCARD.N)

.getResource();

類似地, 屬性的文本值也可以被獲取:

// retrieve the given name property

String fullName = vcard.getProperty(VCARD.FN)

.getString();

在這個例子中, 資源vcard只有一個vcard:FN屬性和一個vcard:N屬性. RDF允許資源有重復的屬性, 例如Adam可能有超過一個的昵稱. 讓我們假設他有兩個昵稱:

// add two nickname properties to vcard

vcard.addProperty(VCARD.NICKNAME, "Smithy")

.addProperty(VCARD.NICKNAME, "Adman");

正如前面所提到的那樣, Jena將RDF模型表示為一組陳述, 所以在模型中新增一個與原有陳述有著相同的主體,謂詞和客體的陳述并不會后什么作用. Jena沒有定義會返回模型中存在的兩個昵稱中的哪一個. Vcard.getProperty(VCARD.NICKNAME)調用的結果是不確定的. Jena會返回這些值中的某一個, 但是并不保證兩次連續的調用會同一個值.

一個屬性很有可能會出現多次, 而方法Resource.listProperty(Property p)可以用來返回一個iterator, 這個iterator會列出所有的值. 此方法所返回的iterator返回的對象的類型為Statement.我們可以像這樣列出所有的昵稱:

// set up the output

System.out.println("The nicknames of /""

+ fullName + "/" are:");

// list the nicknames

StmtIterator iter = vcard.listProperties(VCARD.NICKNAME);

while (iter.hasNext()) {

System.out.println("??? " + iter.nextStatement()

.getObject()

.toString());

}

此代碼可以在Tutorial6中找到, 運行后會產生如下輸出:

The nicknames of "John Smith" are:

Smithy

Adman

一個資源的所有屬性可以用不帶參數的listStatement()方法列出.

________________________________________

查詢模型

前一節討論了如何通過一個有著已知URI的資源來操縱模型. 本節要討論查詢模型. 核心的Jena API只支持一些有限的查詢原語. 對于更強大查詢設備RDQL的介紹不在此文檔中.

列出模型所有陳述的Model.listStatements()方法也許是最原始的查詢模型方式. 然而并不推薦在大型的模型上使用這個方法. 類似的有Model.listSubjects(), 但其所返回的iterator會迭代所有含有屬性的資源, 例如是一些陳述的主體.

Model.listSubjectsWithProperty(Property p, RDFNode o)方法所返回的iterator跌代了所有具有屬性p且p屬性的值為o的資源. 我們可能會預計使用rdf:type屬性來搜索資源的類型屬性以獲得所有的vcard資源:

// retrieve all resource of type Vcard.

ResIterator iter = model.listSubjectsWithProperty(RDF.type, VCARD.Vcard);

然而, 不幸的是, 我們現在正在使用的vcard模式并沒有為vcard定義類型. 然而, 如果我們假設只有類型為vcard的資源才會使用vcard:FN屬性, 并且在我們的數據中, 所有此類資源都有這樣一個屬性, 那么我們就可以像這樣找到所有的vcard:

// list vcards

ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);

while (iter.hasNext()) {

Resource r = iter.nextResource();

...

}

所有的這些查詢方法不過是在原語查詢方法model.listStatements(Select s)上稍做變化而已. 此方法會返回一個iterator, 該iterator會跌代模型中所有被s選中的陳述. 這個selector接口被設計成可擴展的, 但是目前, 它只有一個執行類,那就是com.hp.hpl.jena.rdf.model包中的SimpleSelector類. 在Jena中使用SimpleSelector是很少見的情況, 即當需要直接使用一個特定類而不是使用接口. SimpleSelector的構造函數帶有三個參數:

Selector selector = new SimpleSelector(subject, predicate, object)

這個selector會選擇所有主體與參數subject相配, 謂詞與參數predicate相配, 且客體與參數object相配的陳述.

如果某個參數值為null, 則它表示與任何值均匹配; 否則的話, 它們就會匹配一樣的資源或文本. (當兩個資源有相同的URI或是同一個空白結點時, 這兩個資源就是一樣的; 當兩個文本是一樣的當且僅當它們的所有成分都是一樣的.) 所以:

Selector selector = new SimpleSelector(null, null, null);

會選擇模型中所有的陳述.

Selector selector = new SimpleSelector(null, VCARD.FN, null);

會選擇所有謂詞為VCARD.FN的陳述, 而對主體和客體沒有要求. 作為一個特殊的縮寫,

listStatements( S, P, O )

等同與

listStatements( new SimpleSelector( S, P, O ) )

下面的代碼可以在Tutorial7中找到, 列舉了數據庫中所有vcard中的全名.

// select all the resources with a VCARD.FN property

ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);

if (iter.hasNext()) {

System.out.println("The database contains vcards for:");

while (iter.hasNext()) {

System.out.println("? " + iter.nextStatement()

.getProperty(VCARD.FN)

.getString());

}

} else {

System.out.println("No vcards were found in the database");

}

這個會產生類似如下的輸出:

The database contains vcards for:

Sarah Jones

John Smith

Matt Jones

Becky Smith

你的下一個練習是修改此代碼以使用SimpleSelector而不是使用listSubjectsWithProperty來達到相同的效果.

讓我們看看如何對所選擇的陳述實行更好的控制. SimpleSelector可以被繼承, 它的select方法可以被修改來實現更好的過濾:

// 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) {

public boolean selects(Statement s)

{return s.getString().endsWith("Smith");}

});

這個示例使用了一個簡潔的Java技術, 就是當創建此類的一個實例時重載一個內聯的方法. 這里selects(…)方法會檢查以保證全名以"Smith"做結尾. 重要的是要注意對主體, 謂語和客體的過濾是在調用selects(…)方法之前的執行的, 所以額外的測試只會被應用于匹配的陳述.

完整的代碼可以在Tutorial8中找到, 并會產生如下的輸出:

The database contains vcards for:

John Smith

Becky Smith

你也許會認為下面的代碼:

// do all filtering in the selects method

StmtIterator iter = model.listStatements(

new

SimpleSelector(null, null, (RDFNode) null) {

public boolean selects(Statement s) {

return (subject == null?? || s.getSubject().equals(subject))

&& (predicate == null || s.getPredicate().equals(predicate))

&& (object == null??? || s.getObject().equals(object))

}

}

});

等同于:

StmtIterator iter =

model.listStatements(new SimpleSelector(subject, predicate, object)

雖然在功能上它們可能是等同的, 但是第一種形式會列舉出模型中所有的陳述, 然后再對它們進行逐一的測試. 而第二種形式則允許執行時建立索引來提供性能. 你可以在一個大模型中自己試試驗證一下, 但是現在先為自己倒一杯咖啡休息一下吧.

________________________________________

對模型的操作

Jena提供了把模型當作一個集合整體來操縱的三種操作方法. 即三種常用的集合操作:并, 交和差.

兩個模型的并操作就是把表示兩個模型的陳述集的并操作. 這是RDF設計所支持的關鍵操作之一. 它此操作允許把分離的數據源合并到一起. 考慮下面兩個模型:

和?

當它們被合并時, 兩個http://...JohnSmith會合并成一個, 重復的vcard:FN箭頭會被丟棄, 此時就會產生:

讓我們看一下這個代碼的功能(完整的代碼在Tutorial9中), 再看看會發生什么.

// read the RDF/XML files

model1.read(new InputStreamReader(in1), "");

model2.read(new InputStreamReader(in2), "");

// merge the Models

Model model = model1.union(model2);

// print the Model as RDF/XML

model.write(system.out, "RDF/XML-ABBREV");

petty writer會產生如下的輸出:

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">

John@somewhere.com

John

Smith

John Smith

即便你不熟悉RDF/XML的語法細節, 你仍然可以清楚的看見模型如同預期般被合并了. 我們可以在類似的方式下運算模型的交操作和差操作.

________________________________________

容器

RDF定義了一類特殊的資源來表示事物的集合. 這些資源稱為容器. 一個容器的成員可以是資源也可以是文本. 有三類容器:

一個BAG是一個無序的集合.

一個ALT是一個用來表示備選項的無序的集合.

一個SEQ是一個有序的集合.

一個容器由一個資源表示. 該資源會有一個rdf:type屬性, 屬性值為rdf:Bag, 或rdf:Alt, 或是rdf:Seq, 再或是這些類型的子類型, 這取決于容器的類型. 容器的第一個成員是容器的rdf:_1的屬性所對應的屬性值; 第二個成員是容器的rdf:_2屬性的值, 依此類推. 這些rdf:_nnn屬性被稱為序數屬性.

例如, 一個含有Smith的vcard的簡單bag容器的模型可能會看起來是這樣的:

雖然bag容器的成員們被rdf:_1,rdf_2等等的屬性所表示, 但是這些屬性的順序卻并不重要. 即便我們將rdf:_1和rdf:_2的屬性值交換, 但是交換后的模型仍然表示相同的信息.

Alt是設計用來表示被選項的. 例如, 我們假定有一個表示軟件產品的資源. 它可能有一個屬性指示從哪里可以獲得次軟件產品. 這個屬性值可能是一個包含各種下載地址的Alt集合. Alt是無序的, 除了rdf:_1屬性有著特殊的意義, 它表示默認的選項.

盡管我們可以用基本的資源和屬性機制來處理容器, Jena為處理容器設計了顯式的接口和執行類. 要避免在使用一個對象來操作容器的同時去使用低層方法來改變容器.

讓我們修改Tutorial8以創建一個bag:

// create a bag

Bag smiths = model.createBag();

// 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) {

public boolean selects(Statement s) {

return s.getString().endsWith("Smith");

}

});

// add the Smith's to the bag

while (iter.hasNext()) {

smiths.add(iter.next().getSubject());

}

如果我們將次模型輸出可以看見它含有類似如下的成分:

xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'

xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'

>

...

這表示了Bag資源.

容器接口提供了一個iterator來列舉容器的內容:

// print out the members of the bag

NodeIterator iter2 = smiths.iterator();

if (iter2.hasNext()) {

System.out.println("The bag contains:");

while (iter2.hasNext()) {

System.out.println("? " +

(Resource) iter2.next())

.getProperty(VCARD.FN)

.getString());

}

} else {

System.out.println("The bag is empty");

}

并會產生如下的輸出:

The bag contains:

John Smith

Becky Smith

本例的可執行代碼可以在Tutorial10中找到.

Jena類所提供的操縱容器的方法包括增加新成員, 在容器中間插入新成員和刪除已有的成員. Jena容器類目前保證所使用的序數屬性列表會從rdf:_1開始并且是相鄰的. RDF核心工作小組放松了此項限制, 以允許有局部的容器表示. 所以這是Jena將來可能會修改的地方之一.

________________________________________

關于文本(Literals)和數據類型的更多探討

RDF文本(literals)并不僅僅是簡單的字符串而已. 文本可能有一個語言標簽來指示該文本使用的語言. 有英語語言標簽的文本"chat"會被認為與有著法語語言標簽的文本"chat"是不同的. 這個奇怪的特性是原有RDF/XML語法產生的贗象(artefact).

另外, 事實上共有兩種文本. 在一種里, 字符串成分只是簡單的字符串. 而在另一種里, 字符串成分被預計為格式良好的XML片段. 當一個RDF模型被寫成RDF/XML形式時, 一個特殊的使用parseType='Literal'的屬性(attribute)構造會被使用來表示它.

在Jena中, 當一個文本被創建時, 這些屬性就被設置了. 例如, 在Tutorial11中:

// create the resource

Resource r = model.createResource();

// add the property

r.addProperty(RDFS.label, model.createLiteral("chat", "en"))

.addProperty(RDFS.label, model.createLiteral("chat", "fr"))

.addProperty(RDFS.label, model.createLiteral("chat", true));

// write out the Model

model.write(system.out);

會產生:

xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'

xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'

>

chat

chat

chat

如果兩個文本被認為是相同的, 它們一定都是XML的文本或都是簡單的文本. 另外, 它們兩個要么都沒有語言標簽, 要么有相同的語言標簽. 對簡單的文本而言, 兩者的字符串一定是相同的. XML文本的等同有兩點要求. 第一, 前面提到的要求必須被滿足并且字符串必須相同. 第二, 如果它們字符串的cannonicalization一樣的話, 它們就是一樣的.(譯者注: 找不到cannonicalization中文的解釋.).

Jena接口也支持類型文字. 老式的對待類型文字的方法是把他們當成是字符串的縮寫: 有類型的值會通過Java的常用方法轉換為字符串, 并且這些字符串被存儲在模型中. 例如, 可以試一試(注意:對于簡單類型文字, 我們可以省略對model.createLiteral(…)的調用):

// create the resource

Resource r = model.createResource();

// add the property

r.addProperty(RDFS.label, "11")

.addProperty(RDFS.label, 11);

// write out the Model

model.write(system.out, "N-TRIPLE");

因為兩個文本都是字符串"11", 所以只會有一個陳述被添加.

RDF核心工作小組定義了支持RDF數據類型的機制. Jena支持那些使用類型文字的機制; 但是本教程中不會對此討論.

________________________________________

術語表

空白結點

表示一個資源, 但是并沒有指示該資源的URI. 空白結點的作用如同第一邏輯中的存在符合變量.

Dublin 核心

一個關于網絡資源的元數據標準. 更詳細的信息可以在Dublin Core web site找到.

文本

一個可以作為屬性值的字符串.

客體

三元組的一部分, 也就是陳述的值.

謂詞

三元組的屬性部分.

屬性

屬性(property)是資源的一個屬性(attribute). 例如, DC.title是一個屬性, RDF.type也是一個屬性.

資源

某個實體. 它可以是一個網絡資源, 例如一個網頁; 它也可以是一個具體的物理對象, 例如一棵樹或一輛車; 它也可以是一個抽象的概念, 例如國際象棋或足球. 資源由URI命名.

陳述

RDF模型中的一個箭頭, 通常被解理解為一個事實

主體

RDF模型中箭頭出發點的那個資源.

三元組

一個含有主體, 謂詞和客體的結構. 是陳述的另一種稱呼.

________________________________________

腳注

RDF資源的標簽可以包括一個片段標簽, 例如http://hostname/rdf/Tutorial/#ch-Introduction, 所以, 嚴格地講, 一個RDF資源是由一個URI表示的.

文本可以表示為一個字符串, 也可以有一個可選的語言編碼來表示該字符串的語言. 例如, 文本可能有一個表示英語的語言編碼"en", 而文本"deux"可能有一個表示法語的語言編碼"fr".

總結

以上是生活随笔為你收集整理的mysql jena rdf_RDF和Jena RDF API简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 嫩草免费视频 | 色综合一区二区三区 | 香蕉视频网页版 | 欧洲中文字幕日韩精品成人 | 亚洲精品在线视频 | 色网导航站 | 秋霞黄色片 | 男人日女人的网站 | 日韩精品一区在线播放 | 日韩一级欧美 | 国产av不卡一区二区 | 环太平洋3:泰坦崛起 | 欧美一区二区三区久久成人精品 | 男男做性免费视频网 | 久久综合第一页 | 操干视频| 爱情岛论坛亚洲品质自拍视频 | 女女av在线 | av片大全| 亚洲无人区码一码二码三码的含义 | proumb性欧美在线观看 | 久久综合九色综合网站 | 国产亚洲精品女人久久久久久 | 久操综合 | 日韩欧美精品一区二区 | 少妇 av| 成人aaaa| 欧美日韩亚洲系列 | 精品动漫一区二区三区在线观看 | 男人的天堂2019 | 亚洲五月六月 | 欧洲成人午夜精品无码区久久 | 日韩九九九 | 视频一区 中文字幕 | 黑丝啪啪| 色综合久久88 | 成人自拍网站 | 日韩欧美综合视频 | 97久久精品人人澡人人爽 | 狠狠丁香| 久久9久久| 国产日韩欧美精品 | www色中色 | 亚洲欧美第一页 | а√天堂8资源中文在线 | 韩国禁欲系高级感电影 | 法国空姐在线观看视频 | 日韩一区二区三区在线免费观看 | 亚洲经典久久 | a级片在线观看视频 | 欧美自拍偷拍一区二区 | 中文字幕第一页在线播放 | 日韩欧美在线中文字幕 | 日本一级大片 | 无人在线观看高清视频 单曲 | 日本黄色xxxxx | 蜜乳av网站| 少女忠诚电影高清免费 | 亚洲天堂一区二区 | 黄色应用在线观看 | 一区二区精品免费 | 亚洲av无码乱码国产精品久久 | 午夜小视频在线观看 | 亚洲操图 | 亚洲精品白浆高清久久久久久 | 中文字幕在线观看视频网站 | 日韩黄大片 | 黄色片链接 | 新91视频在线观看 | 日韩精品视频一区二区 | 手机在线中文字幕 | 国产精品天美传媒入口 | 中文字幕高清一区 | www.国产免费 | 少妇人妻综合久久中文字幕 | 久久成人18免费观看 | 极品久久久久 | 光溜溜视频素材大全美女 | 波多野结衣国产在线 | 久久久久免费精品 | 日本欧美一区二区 | 操人视频免费 | 国内自拍视频在线观看 | 婷婷久久综合 | 少妇2做爰hd韩国电影 | 国产区第一页 | brazzers精品成人一区 | 国产免费www | 中国免费观看的视频 | 久久久久女人精品毛片九一 | 波多野结衣啪啪 | 美女脱了内裤喂我喝尿视频 | 国产精品va在线观看无码 | 免费观看黄一级视频 | 成人欧美一区二区三区小说 | 99视频只有精品 | 久久影视一区二区 | 国产免费一区二区三区网站免费 | www.爆操|