我正在使用开源的dbpedia浏览器来处理sparql查询。我试图从ds:birthDate的xs:date中解析月和日值。它不是dateTime所以我不能使用month()或dayOfWeek()函数。我转而使用substr,它可以完美地运行一个月。但是,尝试使用值9,2进行子字符串会给出无效的索引错误。所以我修改了sparql以显示字符串和strlen值,现在我完全糊涂了。它显示的字符串是一个有效的日期格式“yyyy-mm-dd”,它是10个字符。但是,它显示了一个7的strlen。
以下是查询:
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?name, ?bmonth, ?bstring, ?len1, ?len2
WHERE {
?person foaf:name ?name .
?person dbo:birthDate ?birth .
BIND (str(?birth) AS ?bstring)
BIND (strlen(?bstring) AS ?len1)
BIND (substr(?bstring, 6,2) AS ?bmonth)
BIND (strlen(?bstring) AS ?len2)
FILTER ( ?bmonth = '12' )
} GROUP BY ?person ORDER BY ?len1 LIMIT 50
以下是几行结果:
name bmonth bstring len1 len2
"Ann Ronell"@e "12" "1906-12-28" 7 7
"Anna Freud"@en "12" "1895-12-03" 7 7
"Dorothy Lamour"@en "12" "1914-12-10" 7 7
"Doug Mohns"@en "12" "1933-12-13" 7 7
基本上,我真的只是想从字符串中获取dayOfMonth值。但是,如果有人也可以向我解释它是如何提出的7我真的很感激它!
答案 0 :(得分:4)
SPARQL 1.1有一个day
函数,它返回dateTime的日期。
17.4.5.4 day
xsd:integer DAY (xsd:dateTime arg)
以整数形式返回arg的日期部分。
此功能对应fn:day-from-dateTime。
day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) => 10
您可以使用xsd:dateTime
作为功能将xsd:date
转换为可以应用此功能的dateTimes
。举个例子:
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?month ?day where {
# Provide some values for ?date. Note that
# we can use xsd:date *and* xsd:dateTime here,
# as both can be cast to xsd:dateTime.
values ?date {
"2011-01-02"^^xsd:date
"2012-10-11"^^xsd:date
"2013-12-30T14:45:13.815-05:00"^^xsd:dateTime
}
# Cast to a xsd:dateTime and extract the day and month.
bind( day(xsd:dateTime(?date)) as ?day )
bind( month(xsd:dateTime(?date)) as ?month )
}
---------------
| month | day |
===============
| 01 | 02 |
| 10 | 11 |
| 12 | 30 |
---------------
最简单的方法是找出长度 7的值,并且看看你得到了什么。例如,看看
的结果SELECT ?person ?birth WHERE {
?person dbpedia-owl:birthDate ?birth .
bind( strlen(str(?birth)) as ?blen )
filter( ?blen < 10 )
}
LIMIT 25
Person Birth
-----------------------------------------------------------------------------------------
Alyson_No%C3%ABl "--12-03"^^<http://www.w3.org/2001/XMLSchema#gMonthDay>
Corneille_(singer) "--03-24"^^<http://www.w3.org/2001/XMLSchema#gMonthDay>
Count_Karl_Sigmund_von_Hohenwart "--02-12"^^<http://www.w3.org/2001/XMLSchema#gMonthDay>
David_Lewis_(politician) "--06-23"^^<http://www.w3.org/2001/XMLSchema#gMonthDay>
… …
有些值不是xsd:dateTimes
或xsd:date
s,而是xsd:gMonthDay
s。这些没有指定年份,因此字符串不像xsd:date
那样长。这是另一个原因,说明为什么你应该转换为xsd:date
(或检查数据类型等,因为你不能从xsd:gMonthDay
转换为xsd:dateTime
。
正如评论中指出的那样,您的查询实际上并不合法。您应该无法选择未分组的变量,因此或许正在发生的事情是,当您完成时
SELECT ?name, ?bmonth, ?bstring, ?len1, ?len2 WHERE {
?person foaf:name ?name .
?person dbo:birthDate ?birth .
BIND (str(?birth) AS ?bstring)
BIND (strlen(?bstring) AS ?len1)
BIND (substr(?bstring, 6,2) AS ?bmonth)
BIND (strlen(?bstring) AS ?len2)
FILTER ( ?bmonth = '12' )
}
GROUP BY ?person
ORDER BY ?len1
LIMIT 50
您获得了一些DBpedia特定的行为。例如,也许你是按人分组,然后选择是做一个隐含的sample
,也许这些人中有一些人的出生日期有多个值。 (我不确定这一点,这只是我发生的一种可能性。目前DBpedia正在进行维护,因此我无法检查那里有哪些数据,即使我可以,这也是标准未定义的行为我建议您在sparql.org's query validator检查您的查询并首先获得合法的SPARQL。只有这样我们才能判断您是否返回它应该的内容。)