Как преобразовать xsd: dateTime литерал в xsd: date в GraphDB? - PullRequest
1 голос
/ 03 октября 2019

Я пытаюсь преобразовать xsd: dateTime в xsd: date, чтобы иметь возможность фильтровать объекты только по датам. Но, выполнив следующие действия в GraphDB

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?s ?e { 
    VALUES (?start ?end) {("2011-02-02T14:45:14"^^xsd:dateTime "2011-02-04T14:45:13"^^xsd:dateTime)}
    BIND ( xsd:date(?start) AS ?s)
    BIND ( xsd:date(?end) AS ?e)
}

, я получаю следующую ошибку

org.eclipse.rdf4j.query.QueryEvaluationException: Unknown function 'http://www.w3.org/2001/XMLSchema#date'

Но, как можно видеть здесь Функции GraphDB Javascript , используется xsd: функция даты.

Ответы [ 2 ]

3 голосов
/ 04 октября 2019

В документации по ссылке о функциях GraphDB Javascript используется несуществующая функция xsd:date. По какой-то причине это не закончилось в релизе.

Некоторые технические заметки.

Значения RDF, передаваемые в качестве аргументов пользовательским функциям javascript, подвергаются преобразованию типов. Экземпляры org.eclipse.rdf4j.model.IRI и org.eclipse.rdf4j.model.BNode передаются "как есть", но литералы преобразуются следующим образом:

  • , если это целочисленный тип данных, например, один из (xsd: integer, xsd: long, xsd: int, xsd: byte, xsd: short, xsd: nonPositiveInteger, xsd: absoluteInteger, xsd: nonNegativeInteger, xsd: positiveInteger, xsd: unsignedLong, xsd: unsignedInt, xsd: unsigned: unsigned)переданное значение равно long

  • , если оно имеет одно из следующих значений: xsd: десятичное, xsd: float или xsd: double, переданное значение равно double

  • если это одно из следующих значений: xsd: dateTime, xsd: дата, xsd: время, xsd: gYearMonth, xsd: gMonthDay, xsd: gYear, xsd: gMonth или xsd: gDay, переданное значение является экземпляромjavax.xml.datatype.XMLGregorianCalendar

  • если это длительность, например одно из: xsd: duration, xsd: dayTimeDuration или xsd: yearMonthDuration, передаваемое значение является экземпляром javax.xml.datatype.Duration

  • наконец, для xsd: логическое значение равно boolean

  • для всего остального, метка литерала как String

В качестве альтернативы, возвращаемое значение также преобразуется. Если это экземпляр org.eclipse.rdf4j.Value, преобразование не выполняется. В противном случае преобразование в литерал RDF зависит от его типа, а также от того, что доступно в RDF4J ValueFactory как createLiteral методах, которые могут их обработать, включая XMLGregorianCalendar. Поэтому, если нет определенного обработчика, строковое значение результата используется для создания литерала.

В примере из первого ответа результат jsfn:convertDate имеет тип jdk.nashorn.internal.objects.NativeDate, поэтому при создании литерала результата плагин вызывает его toString, что приводит к результатам типа [Date 2011-02-02T14:45:14.000Z]

Кроме того, механизм сценариев в плагине ограничен, чтобы иметь доступ только к классам, начинающимся с java.lang. (исключая java.lang.Thread), org.eclipse.rdf4j.model. и com.ontotext.trree.sdk.

ИмеяПринимая во внимание вышеупомянутые примечания и ограничения, функция javascript, которая преобразует xsd:dateTime в xsd:date, должна установить для полей календарного значения, которые относятся ко времени, значение DatatypeConstants.FIELD_UNDEFINED, которое на самом деле Integer.MIN_VALUE, и создать литералчерез RDF4J ValueFactory:

PREFIX jsfn:<http://www.ontotext.com/js#>
INSERT DATA {
    [] jsfn:register '''
    function convertDate(value) {
        value.setTime(java.lang.Integer.MIN_VALUE, java.lang.Integer.MIN_VALUE, java.lang.Integer.MIN_VALUE);
        return org.eclipse.rdf4j.model.impl.SimpleValueFactory.getInstance().createLiteral(value);
    }
'''
}

HTH

1 голос
/ 03 октября 2019

Создайте функцию JavaScript в GraphDB следующим образом:

PREFIX jsfn:<http://www.ontotext.com/js#>
INSERT DATA {
    [] jsfn:register '''
    function convertDate(value) {
        return new Date(value);
    }
'''
}

Убедитесь, что функция зарегистрирована или:

PREFIX jsfn:<http://www.ontotext.com/js#>
SELECT ?s ?o {
    ?s jsfn:enum ?o
}

И затем используйте ее следующим образом:

PREFIX jsfn:<http://www.ontotext.com/js#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?s ?e { 
    VALUES (?start ?end) {("2011-02-02T14:45:14"^^xsd:dateTime "2011-02-04T14:45:13"^^xsd:dateTime)}
    BIND ( jsfn:convertDate(?start) AS ?s)
    BIND ( jsfn:convertDate(?end) AS ?e)
}

Возвращенный результат:

[Дата 2011-02-02T14: 45: 14.000Z]

[Дата 2011-02-04T14: 45: 13.000Z]

Надеюсь, это поможет.

...