简体   繁体   中英

Conditional Binding in SPARQL/CONSTRUCT

I have a SPARQL CONSTRUCT that works like this:

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. With the syntax above, I get ?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.

Any solution?

EDIT : The solution by Scott works for common graph-based queries. The case I came from involves the use of VALUES, is more complicated and I couldn't find a solution so far.

EDIT/2 : the error-triggering solution , suggested by Andy in the Jena mailing list, works fine! 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:

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM