2008-12-17 53 views
1

我需要保留幾個Jena模型(具體而言,OntModels)跨套接字進行同步,並且我想每次都做一次更改(出於各種原因 - 其中一個原因是每個Statement添加或從OntModels中刪除也適應JESS規則庫)。我能夠聽取OntModels上的添加/刪除事件,然後創建簡單的事件實例,這些實例將添加/刪除的語句以及指示添加或刪除語句的ChangeType一起包裝,但序列化語句已被證明是一個問題。序列化JENA OntModel更改

不幸的是,我發現的所有JENA序列化文檔都涉及到將整個模型序列化到xml/rdf/n3 /等等。由於語句只是字符串的三元組(無論如何),它似乎就像它應該很簡單,以便在Statement級別序列化數據。但是,Jena似乎沒有提供用於「用正確的方式」的普通字符串來創建語句的API。類型文字出現問題。例如:

我可以創建聲明:

<http://someuri/myont#foo> <http://someuri/myont#weight> "50.7"^^www.w3.org/2001/XMLSchema#double 

但字符串版本,我可以出去看起來是這樣的:

"http://someuri/myont#foo" "http://someuri/myont#weight" "50.7^^www.w3.org/2001/XMLSchema#double" 

(注意不存在的「前^^ )

這不會是太大的問題,因爲文字仍然可以用正則表達式解析出來,但是我一直無法用正確的文字創建一個Statement。明顯的方法(ModelC on.createStatement(Resource,Property,String))會生成一個無類型的字符串文本,其中傳入的字符串的全部值爲

有誰知道我如何可靠地序列化(和反序列化,當然)單個耶拿語句?

回答

2

我會序列化N-TRIPLES格式的變化。 Jena內置了N-TRIPLES序列化器和解析器,但是N-TRIPLES語法非常簡單(故意),因此在代碼中手動生成將很容易。

但是,它可能是更容易讓普通MEM模型周圍舉行的變化,有事件處理程序變動寫入該模型,然後根據您的同步計劃序列化模型在電線。同樣,在遠端,我會將同步通道的更新讀入臨時存儲模型,然後yourOntModel.add(changesModel)應該非常直接地添加更新。

伊恩

+0

N-triples語法實際上是我正在使用的(並最終使用的)問題是在檢測文字期間反序列化。 (你現在可以在這裏看到我的方法)。儘管使用模型序列化可能是最強大的。 – rcreswick 2009-01-14 00:12:28

1

不是我曾經深入研究過的領域,但我記得Talis正在做一些研究,並且能夠將follow breadcrumbs添加到名爲「Changeset」的相關詞彙表中。

http://vocab.org/changeset/schema

我很驚訝你有連載使用JENA個人陳述的問題,但也許如果你根據變更模式創建一個圖,序列圖,你就會有更多的運氣?或者,將該語句添加到新圖形中,並將一個tripple的圖形序列化。

+0

這可能是最好的方法 - 如果需要出現我可能會考慮保持一個模型只是爲了序列化/反序列化的目的。 (每次更改被推送到模型,模型被序列化,然後被清除,以便進行下一組更改。) – rcreswick 2009-01-14 00:10:31

0

也許你應該嘗試通過Model.createLiteral(字符串)取代的createStatement的字符串參數...

+0

不幸的是,我不*總是*序列化文字。 – rcreswick 2009-01-14 00:03:44

0

我結束了該解決方案如下。由於時間限制(我直到最近纔看到關於此問題的其他建議),所以我最終使用了reg-ex方法

這可能不是最好的方法,但它似乎運作良好(和我我已經用一個測試套件對它進行了審查,該測試套件可以演示我現在需要處理的用例)。

createStatement(...)方法位於OntUtilities輔助類中。

/** 
    * Serialization output method. 
    * 
    * @param out 
    * @throws IOException 
    */ 
    private void writeObject(final ObjectOutputStream out) throws IOException { 
    out.defaultWriteObject(); 
    out.writeObject(_statement.getSubject().getURI()); 
    out.writeObject(_statement.getPredicate().getURI()); 
    out.writeObject(_statement.getObject().toString()); 
    } 

    /** 
    * deserialization method. 
    * 
    * @param in 
    * @throws IOException 
    * @throws ClassNotFoundException 
    */ 
    private void readObject(final ObjectInputStream in) throws IOException, 
     ClassNotFoundException { 
    in.defaultReadObject(); 

    final String subject = (String)in.readObject(); 
    final String predicate = (String)in.readObject(); 
    final String object = (String)in.readObject(); 

    _statement = OntUtilities.createStatement(subject, predicate, object); 
    } 

    /** 
    * Creates a statement from a triple of strings. These strings may be fully 
    * qualified uris, or shortened "namespace" uris (eg: shai:TST) 
    * 
    * @param sub The resource uri (the subject) 
    * @param pred The predicate uri (the property) 
    * @param ob The object uri. 
    * @return A JENA Statement. 
    */ 
    public static Statement createStatement(final String sub, final String pred, 
     final String ob) { 
     final Model m = ModelFactory.createDefaultModel(); 

     final String s = OntUtilities.nsUriToUri(sub); 
     final String p = OntUtilities.nsUriToUri(pred); 
     final String o = OntUtilities.nsUriToUri(ob); 

     Statement stmt = null; 
     try { 
     // try making a uri as a syntax-verification step. 
     new URI(o); 
     // it was valid, so well use o as a resource: 
     final Resource obj = m.createResource(o); 
     stmt = m.createStatement(m.createResource(s), m.createProperty(p), obj); 
     } catch (final URISyntaxException e) { 
     // o was *not* a uri. 
     if (o.contains("^^")) { 
      final int idx = o.lastIndexOf("^^"); 

      final String value = o.substring(0, idx); 
      final String uri = o.substring(idx+2); 

      final Literal lit = m.createTypedLiteral(value, getDataType(uri)); 

      stmt = m.createStatement(m.createResource(s), m.createProperty(p), lit); 
     } else { 
      // just use the string as-is: 
      stmt = m.createStatement(m.createResource(s), m.createProperty(p), o); 
     } 
     } 
     return stmt; 
    }