首页 > 解决方案 > 如何在 GraphDB 中将 xsd:dateTime 文字转换为 xsd:date?

问题描述

我正在尝试将 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 函数的用法。

标签: sparqlgraphdb

解决方案


来自关于 GraphDB Javascript Functions 链接的文档使用了一个不存在的函数xsd:date。由于某种原因,它并没有在发布中结束。

一些技术说明。

作为参数传递给用户定义的 javascript 函数的 RDF 值会进行类型转换。org.eclipse.rdf4j.model.IRI和的实例org.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:unsignedInt、xsd:unsignedShort 和 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,则不进行任何转换。ValueFactory否则,转换为 RDF 文字取决于它的类型以及RDF4JcreateLiteral中可以处理这些的方法,包括XMLGregorianCalendar. 因此,如果没有特定的处理程序,则使用结果的字符串值来创建 Literal。

在第一个答案的示例中,结果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.

考虑到上述注意事项和限制,将 a 转换xsd:dateTime为需要设置与实际xsd:date时间相关的日历值字段并通过 RDF4J 构造 Literal 的 javascript 函数:DatatypeConstants.FIELD_UNDEFINEDInteger.MIN_VALUEValueFactory

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);
    }
'''
}

高温高压


推荐阅读