序列化JENA OntModel更改

时间:2008-12-17 18:48:23

标签: java serialization jena ontology

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

不幸的是,我发现的所有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。显而易见的方法(ModelCon.createStatement(Resource,Property,String))生成一个无类型的字符串文字,其中传入了String的完整值。

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

4 个答案:

答案 0 :(得分:2)

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

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

伊恩

答案 1 :(得分:1)

不是我深入研究过的一个领域,但我记得Talis正在做一些研究,能够follow breadcrumbs得到名为“Changeset”的相关词汇。

http://vocab.org/changeset/schema

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

答案 2 :(得分:0)

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

答案 3 :(得分: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; 
   }