SPARQL/CONSTRUCT中的条件绑定

SPARQL/CONSTRUCT中的条件绑定,sparql,Sparql,我有一个SPARQL构造,其工作原理如下: 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 ) } 问题

我有一个SPARQL构造,其工作原理如下:

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 )
}
问题是当
?f
既不是0也不是1(但仍然有一些值)时,我根本不希望
有值。使用上面的语法,我得到
?uri有值'
。如果我能给
?v
分配某种类型的“null”,或者避免绑定,这将是可行的,但我在规范中找不到类似的东西

有解决办法吗

编辑:该工具适用于常见的基于图形的查询。我的案例涉及到价值观的使用,到目前为止我还没有找到解决方案


编辑/2:安迪在杰娜邮件列表中建议的方法很好用!我发现另一种更具可读性的方法是,当我们想要跳过原始值时

有点老套,但应该创建一个空白节点,然后过滤掉这些节点:

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

有点老套,但应该创建一个空白节点,然后过滤掉这些节点:

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

根据评论中的反馈,以下是一个基于
可选
的解决方案,该解决方案应满足所有标准:

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)
  }
}
如前所述,前面的解决方案将不包括有标签的情况,但是
?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 )
}

根据评论中的反馈,以下是一个基于
可选
的解决方案,该解决方案应满足所有标准:

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)
  }
}
如前所述,前面的解决方案将不包括有标签的情况,但是
?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 )
}

抱歉,否。此操作将跳过带?f!=(0,1),而在这种情况下,我只想省略has值三元组(并保留rdfs:label或其他任何内容)。尝试使用optional,但不起作用。它暴露了SPARQL
IF
中的一个明显缺陷。如果SPRQL只允许
然后
表达式,即不需要
否则
,那么只需在原始查询中删除该表达式即可。所有这些尝试都只是试图绕过这个缺陷。是的,我问的问题是可选的。问题是我来自它的一个变体,涉及到值构造,似乎没有解决方案:我会说IF()很好,因为它是一个函数,它必须返回一些东西(除其他外,为了避免SPARQL实现者遇到困难)。问题是没有一个函数(或常量)返回表示“未绑定”的内容。在VALUES子句中,您可以使用UNDEF,但在其他任何地方都不能使用。抱歉,不能使用。这将跳过带有?f!=(0,1),而在这种情况下,我只想省略has值三元组(并保留rdfs:label或其他任何内容)。尝试使用optional,但不起作用。它暴露了SPARQL
IF
中的一个明显缺陷。如果SPRQL只允许
然后
表达式,即不需要
否则
,那么只需在原始查询中删除该表达式即可。所有这些尝试都只是试图绕过这个缺陷。是的,我问的问题是可选的。问题是我来自它的一个变体,涉及到值构造,似乎没有解决方案:我会说IF()很好,因为它是一个函数,它必须返回一些东西(除其他外,为了避免SPARQL实现者遇到困难)。问题是没有一个函数(或常量)返回表示“未绑定”的内容。在VALUES子句中,您可以使用UNDEF,但在其他任何地方都不能使用。请参阅上面的注释,这将跳过任何关于没有0/1的节点的三元组。然后将第二部分放入可选子句?请参阅上面的注释,这将跳过任何关于没有0/1的节点的三元组。然后将第二部分放入可选子句?