簡體   English   中英

SHACL比較兩個不同節點的值?

[英]SHACL to compare values on two different nodes?

我正在嘗試為日期比較編寫SHACL約束,其中開始日期必須小於或等於結束日期。 使用:beginDate:endDate謂詞將日期附加到同一節點時,約束是直截了當的:

:StartEndRuleShape a :PropertyShape  ;
  sh:path              :beginDate ;
  sh:lessThanOrEquals  :endDate ;
  sh:message "Begin Date is after End Date." .

現實世界模型更復雜。 在附圖中,注意如何:AnimalSubject hasReferenceInterval ReferenceInterval IRI具有:ReferenceBegin和a :ReferenceEnd ,它們又使用time:inXSDDate謂詞分配日期值。 在這種情況下如何應用約束以確保ReferenceBegin值等於或小於ReferenceEnd值? 這是使用SHACL-SPARQL還是sequencePath的情況? 我一直無法找到好的例子。 干杯! 在此輸入圖像描述

我在違反約束的數據上測試了以下SHACL-SPARQL:ReferenceBegin =“2016-12-07”,ReferenceEnd =“2016-12-06”,但驗證報告未檢測到違規。 如果我自己運行SPARQL,它會選擇觀察。 有什么想法嗎? 我正在使用Stardog / Stardog Studio並在他們的用戶支持平台上發布。

@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix sh:  <http://www.w3.org/ns/shacl#> .
@prefix time: <http://www.w3.org/2006/time#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix :     <http://foo.bar.org/> .

:IntervalShape a sh:NodeShape ;
 sh:targetClass :ReferenceInterval ;
 sh:sparql [
  a sh:SPARQLConstraint ;
  sh:message "End Date must be greater than or equal to Begin Date";
  sh:prefixes [
    sh:declare [
      sh:prefix "time" ;
      sh:namespace "http://www.w3.org/2006/time#"^^xsd:anyURI ;
    ] 
  ] ;
 sh:select
  """SELECT $this (?beginDate AS ?intervalStart) (?endDate AS ?intervalEnd)
    WHERE {
      $this     :hasReferenceInterval ?interval .
      ?interval :ReferenceBegin       ?beginIRI ;
                :ReferenceEnd         ?endIRI .
      ?beginIRI time:inXSDDate        ?beginDate .
      ?endIRI   time:inXSDDate        ?endDate .
      FILTER  (! (?endDate >= ?beginDate ))
    }""" ;
] .

看起來您的約束有兩個問題:

  1. 您在SHACL中聲明time前綴,但不在base前綴中聲明。 你要:

     sh:prefixes [ sh:declare [ sh:prefix "time" ; sh:namespace "http://www.w3.org/2006/time#"^^xsd:anyURI ; ], [ sh:prefix "" ; sh:namespace "http://foo.bar.org/"^^xsd:anyURI ; ] ] ; 
  2. 您的焦點節點是:ReferenceInterval ,但是編寫查詢的方式, $this只會綁定到以下實體:hasReferenceInterval [a :ReferenceInterval] 我重寫了查詢,以便?interval現在是$this如下:

     sh:select """SELECT $this (?beginDate AS ?intervalStart) (?endDate AS ?intervalEnd) WHERE { $this :ReferenceBegin ?beginIRI ; :ReferenceEnd ?endIRI . ?beginIRI time:inXSDDate ?beginDate . ?endIRI time:inXSDDate ?endDate . FILTER (! (?endDate >= ?beginDate )) }""" ; 

    添加此約束,我能夠看到違規。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM