使用IF将变量绑定到两个值之一?

use*_*384 13 rdf if-statement sparql

在下面的SPARQL查询中,我不确定如何使用if两个字符串中的一个绑定到变量?result.我听说有"范围"和"超出范围"的概念,但我并没有真正看到差异.我也尝试将该if条款放在select行中,但它也没有用.如何根据条件修复此查询以绑定?result到两个字符串之一?

SELECT ?result
WHERE{
    ?chain rdf:type rdfs:Property .
    ?chain rdfs:domain <http://www.vs.cs.hs-rm.de/ontostor/SVC#MDiskGroup> .
    ?chain rdfs:range <http://www.vs.cs.hs-rm.de/ontostor/SVC#IOgroup> .
    ?this ?chain ?arg .
    ?arg io:id ?var .
    IF(?var = "0"^^xsd:integer,
       BIND("    *"^^xsd:string AS ?result),
       BIND(""^^xsd:string AS ?result)) .
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*lor 24

ifSPARQL中的运算符不是语句,因为它有时是编程语言,而是函数形式.表达.该if(test,a,b)a,如果test是真的,b如果test是假的.正如文件所说:

17.4.1.2 IF

rdfTerm  IF (expression1, expression2, expression3)
Run Code Online (Sandbox Code Playgroud)

IF函数形式计算的第一个参数,将其解释为 有效布尔值,然后返回的值expression2,如果EBV为真,否则返回的值expression3.只计算expression2和expression3中的一个.如果评估第一个参数会引发错误,则会引发错误以评估IF表达式.

示例:假设?x = 2,?z = 0且?y未在某些查询解决方案中绑定:

IF(?x = 2, "yes", "no")     returns "yes"
IF(bound(?y), "yes", "no")  returns "no"
IF(?x=2, "yes", 1/?z)       returns "yes", the expression 1/?z is not evaluated
IF(?x=1, "yes", 1/?z)       raises an error
IF("2" > 1, "yes", "no")    raises an error
Run Code Online (Sandbox Code Playgroud)

因此,if它不是一个类似于编程语言的语句,但它只是一个函数,它接受三个参数并返回一个值.SPARQL是一种查询语言,没有执行的语句; 它是一种查询语言,用于匹配图形中的模式以及将变量绑定到值.所以if是一个函数,如果第一个参数为true,则返回第二个参数,否则返回第三个参数.通常,您将函数的值绑定到变量

bind( function(args...) as ?variable )
Run Code Online (Sandbox Code Playgroud)

这种情况也不例外.您将调用该if函数并将其结果绑定到变量

bind( if(condition,then,else) as ?result )
Run Code Online (Sandbox Code Playgroud)

在您的情况下,这意味着您将使用以下查询.我添加了一些新行来帮助提高可读性,但它们并不是必需的.SPARQL查询中的整数是具有类型的文字的简写xsd:integer,所以我也使用(感谢RobV的评论)0而不是"0"^^xsd:integer.(参见2.3.2使用数字类型匹配文字.)

bind(if(?var = 0,
        "    *"^^xsd:string,
        ""^^xsd:string )
     as ?result)
Run Code Online (Sandbox Code Playgroud)

如果我们真的想要进一步缩短它,那么我们可以使用它xsd:string作为构造函数,并且做(参见17.5 XPath构造函数):

bind(xsd:string(if(?var = 0,"    *", "")) as ?result)
Run Code Online (Sandbox Code Playgroud)

如果你习惯于做这样的话,这一开始看起来有点奇怪

String result;
if ( var == 0 ) {
  result = "case 1";
}
else {
  result = "case 2";
}
Run Code Online (Sandbox Code Playgroud)

但是许多语言实际上提供了一个三元运算符,可以让你做得更短

String result = (var == 0) ? "case 1" : "case 2";
Run Code Online (Sandbox Code Playgroud)

代替.这是您使用SPARQL获得的功能.