Сериализация изменений JENA OntModel

Мне нужно сохранить пару моделей Йена (в частности, OntModels), синхронизированных через сокет, и я хотел бы делать это по одному изменению за раз (по разным причинам, одна из которых состоит в том, что каждое утверждение, добавленное или удаленное из OntModels, является также адаптируя базу правил JESS.). Я могу прослушивать события добавления / удаления в OntModels, а затем создавать простые экземпляры событий, которые обертывают добавленные / удаленные утверждения вместе с ChangeType, который указывает, что оператор был добавлен или удален, но сериализация утверждения оказалась проблема.

К сожалению, вся документация по сериализации JENA, которую я нашел, относится к сериализации всей модели в xml / rdf / n3 / и т. д. Поскольку операторы представляют собой просто тройки строк (в любом случае на одном уровне), кажется, что это должно быть тривиально для сериализуйте данные на уровне инструкции. Однако Йена, похоже, не предоставляет 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)) генерирует нетипизированный строковый литерал с полным значением переданной String.

Кто-нибудь знает, как я могу надежно сериализовать (и, конечно, десериализовать) отдельные заявления Jena?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
1 720
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Не та область, которую я рассматривал очень подробно, но я вспомнил, что Talis проводила некоторые исследования и смогла следовать панировочным сухарям к соответствующему словарю под названием «Набор изменений».

http://vocab.org/changeset/schema

Я удивлен, что у вас возникли проблемы с сериализацией отдельных операторов с помощью JENA, но, возможно, если бы вы создали график в соответствии со схемой набора изменений и сериализовали граф, вам повезло бы больше? В качестве альтернативы добавьте оператор в новый граф и сериализуйте график из одного тройного числа.

Это может быть лучший подход - если возникнет необходимость, я, вероятно, подумаю о том, чтобы оставить модель только для целей сериализации / десериализации. (каждое изменение передается в модель, модель сериализуется, а затем очищается для следующего набора изменений.)

rcreswick 14.01.2009 03:10
Ответ принят как подходящий

Я бы сериализовал изменения в формате N-TRIPLES. Jena имеет встроенный сериализатор и парсер N-TRIPLES, но синтаксис N-TRIPLES (намеренно) очень прост, поэтому его будет легко сгенерировать вручную в вашем коде.

Однако было бы еще проще сохранить простую модель памяти для хранения изменений, позволить обработчикам событий записывать изменения в эту модель, а затем сериализовать эту модель по сети в соответствии с вашим расписанием синхронизации. Точно так же на дальнем конце я бы прочитал обновления из канала синхронизации во временную модель памяти, тогда yourOntModel.add( changesModel ) должен очень просто добавить обновления.

Ян

Синтаксис N-троек - это, по сути, то, что я использовал (и в конечном итоге использовал), проблема заключалась в обнаружении литералов во время десериализации. (Теперь вы можете увидеть мой подход здесь). Однако использование моделей для сериализации, вероятно, является наиболее надежным.

rcreswick 14.01.2009 03:12

Возможно, вам стоит попробовать заменить параметр String в createStatement на Model.createLiteral (String) ...

К сожалению, я не сериализирую литералы всегда.

rcreswick 14.01.2009 03:03

Решение, к которому я пришел, приведено ниже. В итоге я использовал подход 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; 
   }

Другие вопросы по теме