[英]Conditional Binding in SPARQL/CONSTRUCT
I have a SPARQL CONSTRUCT that works like this: 我有一个SPARQL CONSTRUCT的工作原理是这样的:
CONSTRUCT {
?uri rdfs:label ?label;
foo:has-value ?v.
}
WHERE {
?uri
rdfs:label ?label;
foo:has-flag ?f.
BIND ( IF ( ?f = 0, "Value for Zero", IF ( ?f = 1, "Value for One", '' ) ) AS ?v )
}
The problem is that when ?f
is neither 0 nor 1 (but still has some value) I don't want the has-value
statement at all. 问题是,当
?f
既不是0也不是1(但仍然有一些值)时,我根本就不需要has-value
语句。 With the syntax above, I get ?uri has-value ''
. 使用上面的语法,我得到
?uri has-value ''
。 It would work, if I could assign some sort of "null" to ?v
, or avoid the binding, but I cannot find anything like that in the specs. 如果我可以给
?v
分配某种“空”或避免绑定,那会起作用的,但是我在规范中找不到类似的东西。
Any solution? 有什么办法吗?
EDIT : The solution by Scott works for common graph-based queries. 编辑 : Scott的解决方案适用于基于图形的常见查询。 The case I came from involves the use of VALUES, is more complicated and I couldn't find a solution so far.
我来自的案例涉及VALUES的使用, 情况更为复杂 ,到目前为止我找不到解决方案。
EDIT/2 : the error-triggering solution , suggested by Andy in the Jena mailing list, works fine! EDIT / 2 :由Andy在Jena邮件列表中建议的错误触发解决方案 ,效果很好! Another approach, which I find more readable, is binding an unbound variable when we want to skip the original value.
我发现更具可读性的另一种方法是,当我们想跳过原始值时, 绑定一个未绑定的变量 。
Given feedback in the comments, here is a solution based on OPTIONAL
that should meet all of the criteria: 给定评论中的反馈,以下是基于
OPTIONAL
的解决方案,应满足所有条件:
CONSTRUCT {
?uri rdfs:label ?label;
foo:has-value ?v.
}
WHERE {
?uri rdfs:label ?label .
?uri foo:has-flag ?f.
OPTIONAL { FILTER (?f = 0)
BIND("Value for Zero" AS ?v)
}
OPTIONAL { FILTER (?f = 1)
BIND("Value for One" AS ?v)
}
}
As pointed out, this previous solution will not cover the case where there is label, but ?f
is not 0 or 1: 如所指出的那样,该先前的解决方案将不覆盖有标签但
?f
不是0或1的情况:
CONSTRUCT {
?uri rdfs:label ?label;
foo:has-value ?v.
}
WHERE {
?uri
rdfs:label ?label;
foo:has-flag ?f.
FILTER (?f = 0 || ?f = 1)
BIND ( IF ( ?f = 0, "Value for Zero", IF ( ?f = 1, "Value for One", '' ) ) AS ?v )
}
A bit hacky but should work with creating a blank node and then filter out those: 有点古怪,但是应该创建一个空白节点,然后过滤掉这些节点:
CONSTRUCT {
?uri rdfs:label ?label;
foo:has-value ?v.
}
WHERE {
?uri rdfs:label ?label .
OPTIONAL {
?uri foo:has-flag ?f.
BIND ( IF ( ?f = 0, "Value for Zero",
IF ( ?f = 1, "Value for One", BNODE() )
) AS ?v )
FILTER(!ISBLANK(?v))
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.