1

我需要在一个套接字上保持几个Jena模型(特别是 OntModels)同步,并且我想一次做一个更改(出于各种原因——一个是从 OntModels 添加或删除的每个 Statement 是还适应了 JESS 规则库。)。我能够监听 OntModels 上的添加/删除事件,然后创建简单的事件实例,这些实例将添加/删除的语句与指示添加或删除语句的 ChangeType 一起包装,但序列化语句已被证明是问题。

不幸的是,我发现的所有 JENA 序列化文档都与将整个模型序列化为 xml / rdf / n3 / 等有关。由于语句只是字符串的三元组(无论如何,在一个级别上),它似乎应该是微不足道的在语句级别序列化数据。然而,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"

(注意^^前没有“)

这不是什么大问题,因为文字仍然可以用正则表达式解析出来,但我无法使用正确的文字创建语句。显而易见的方法 (ModelCon.createStatement(Resource, Property, String)) 生成一个无类型的字符串文字,其中包含传入的字符串的完整值。

有谁知道我如何可靠地序列化(当然还有反序列化)单个 Jena 语句?

4

4 回答 4

2

我会以 N-TRIPLES 格式序列化这些更改。Jena 具有内置的 N-TRIPLES 序列化器和解析器,但 N-TRIPLES 语法(故意)非常简单,因此很容易在您的代码中手动生成。

但是,保留一个普通的 mem 模型来保存更改可能更容易,让事件处理程序将更改写入该模型,然后根据您的同步计划通过线路序列化该模型。同样,在远端,我会将同步通道中的更新读取到临时内存模型中,然后yourOntModel.add( changesModel )应该非常直接地添加更新。

伊恩

于 2009-01-10T00:51:20.280 回答
1

不是我深入研究过的领域,但我记得 Talis 正在做一些研究,并且能够按照面包屑导航到名为“Changeset”的相关词汇。

http://vocab.org/changeset/schema

我很惊讶您在使用 JENA 序列化单个语句时遇到问题,但也许如果您根据变更集架构创建一个图表并序列化该图表,您会有更多的运气?或者,将语句添加到新图并序列化一个三元组的图。

于 2009-01-05T14:42:29.067 回答
0

也许您应该尝试将 createStatement 的 String 参数替换为 Model.createLiteral(String)...

于 2009-01-13T16:45:04.877 回答
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; 
   }
于 2009-01-14T00:05:26.003 回答