序列化 JENA OntModel 更改

发布于 2024-07-10 06:44:36 字数 1003 浏览 10 评论 0原文

我需要保持几个 Jena 模型(特别是 OntModels)在套接字上同步,我想一次进行一项更改(出于各种原因——其中之一是从 OntModels 添加或删除的每个语句也在适应 JESS 规则库。)。 我能够监听 OntModel 上的添加/删除事件,然后创建简单的事件实例,将添加/删除的语句与指示添加或删除语句的 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 语句?

I need to keep a couple of Jena Models (OntModels, specifically) synchronized across a socket, and I'd like to do this one change at a time (for various reasons -- one being that each Statement added or removed from the OntModels is also adapting a JESS rule base.). I am able to listen to the add/remove events on the OntModels and then create simple event instances that wrap the added / removed Statements along with a ChangeType that indicates that the Statement was added or removed, but serializing the Statement has proven to be a problem.

Unfortunately, all of the JENA serialization documentation that I've found relates to serializing an entire model to xml / rdf / n3 / etc. Since statements are simply triples of Strings (at one level, anyway) it seems like it should be trivial to serialize the data at the Statement level. However, Jena doesn't seem to provide an API for creating Statements with plain strings that "does the right thing". Problems arise with typed literals. eg:

I can create the statement:

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

but the string version that I can get out looks like this:

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

(note the absence of a " before the ^^)

This wouldn't be that much of a problem, since the literal can still be parsed out with a regex, but I've been unable to create a Statement with the proper literal. The obvious approach (ModelCon.createStatement(Resource, Property, String)) generates an untyped string literal with the full value of the String passed in.

Does anyone know how I can reliably serialize (and deserialize, of course) individual Jena Statements?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

亚希 2024-07-17 06:44:36

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

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

伊恩

I would serialize the changes out in N-TRIPLES format. Jena has built-in N-TRIPLES serializer and parser, but the N-TRIPLES syntax is (deliberately) very simple so it would be easy to generate manually in your code.

However, it might be even easier to keep a plain mem model around to hold the changes, have the event handlers write changes into that model, then serialize that model over the wire according to your synchronization schedule. Likewise, at the far end I would read the updates from the sync channel into a temporary mem model, then yourOntModel.add( changesModel ) should add in the updates very straightforwardly.

Ian

青衫负雪 2024-07-17 06:44:36

这不是我深入研究过的领域,但我记得达丽斯正在进行一些研究,并且能够按照面包屑找到名为“Changeset”的相关词汇。

http://vocab.org/changeset/schema

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

Not an area I've looked at in great depth, but I recalled Talis were doing some research and was able to follow breadcrumbs to the relevant vocabulary called "Changeset".

http://vocab.org/changeset/schema

I'm surprised you had issues serialising individual statements using JENA, but perhaps if you created a graph according to the changeset schema and serialised the graph you'd have more luck? Alternately, add the statement to a new graph and serialise a graph of one tripple.

仙女 2024-07-17 06:44:36

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

Maybe you should try to replace the String parameter of createStatement by Model.createLiteral(String)...

等往事风中吹 2024-07-17 06:44:36

我最终得到的解决方案如下。 由于时间限制,我最终使用了 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; 
   }

The solution I ended up with is below. I ended up using a reg-ex approach because of time constraints (I didn't see the other suggestions on this question until very recently)

This is probably not the best approach, but it seems to work well (and I've vetted it with a test suite that exercise the use cases I need to deal with at this point).

The createStatement(...) method is in an OntUtilities helper class.

   /**
    * 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; 
   }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文