如何在GraphDB中将xsd:dateTime文字转换为xsd:date?

时间:2019-10-03 09:35:44

标签: sparql graphdb

我试图将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 Functions 有一个xsd:date函数的用法。

2 个答案:

答案 0 :(得分:3)

来自链接的有关GraphDB Javascript函数的文档使用了不存在的函数xsd:date。由于某些原因,它并未在发行版中结束。

一些技术说明。

作为参数传递给用户定义的javascript函数的RDF值会进行类型转换。 org.eclipse.rdf4j.model.IRIorg.eclipse.rdf4j.model.BNode的实例按“原样”传递,但文字的转换方式如下:

  • 如果它是整数数据类型,例如(xsd:integer,xsd:long,xsd:int,xsd:byte,xsd:short,xsd:nonPositiveInteger,xsd:negativeInteger,xsd:nonNegativeInteger,xsd:positiveInteger,xsd:unsignedLong,xsd:unsignedInd,和xsd:unsignedByte)传递的值是long

  • 如果它是xsd:decimal,xsd:float或xsd:double之一,则传递的值为double

  • 如果它是以下之一:xsd:dateTime,xsd:date,xsd:time,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是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.Threadorg.eclipse.rdf4j.model.com.ontotext.trree.sdk.

开头的类。

考虑到上述注意事项和限制,将xsd:dateTime转换为xsd:date的javascript函数需要将与时间相关的日历值字段设置为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 :(得分:1)

在GraphDB中创建javascript函数,例如:

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]

希望这会有所帮助。