简体   繁体   English

SHACL比较两个不同节点的值?

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

I am trying to write a SHACL constraint for a date comparison where the start date must be less than or equal to an end date. 我正在尝试为日期比较编写SHACL约束,其中开始日期必须小于或等于结束日期。 When the dates are attached to the same node using the :beginDate and :endDate predicates, the constraint is straight forward: 使用:beginDate:endDate谓词将日期附加到同一节点时,约束是直截了当的:

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

The real world model is more complex. 现实世界模型更复杂。 In the attached diagram, note how an :AnimalSubject hasReferenceInterval . 在附图中,注意如何:AnimalSubject hasReferenceInterval ReferenceInterval IRIs have a :ReferenceBegin and a :ReferenceEnd , which are in turn assigned the date value using the time:inXSDDate predicate. ReferenceInterval IRI具有:ReferenceBegin和a :ReferenceEnd ,它们又使用time:inXSDDate谓词分配日期值。 How can I apply the constraint in this case to ensure the ReferenceBegin value is equal to or less than ReferenceEnd value? 在这种情况下如何应用约束以确保ReferenceBegin值等于或小于ReferenceEnd值? Is this a case for using SHACL-SPARQL, or sequencePath ? 这是使用SHACL-SPARQL还是sequencePath的情况? I've been unable to find good examples of either. 我一直无法找到好的例子。 Cheers! 干杯! 在此输入图像描述

I tested the following SHACL-SPARQL on data that violates the constraint: ReferenceBegin = "2016-12-07", ReferenceEnd = "2016-12-06", but the Validation Report does not detect the violation. 我在违反约束的数据上测试了以下SHACL-SPARQL:ReferenceBegin =“2016-12-07”,ReferenceEnd =“2016-12-06”,但验证报告未检测到违规。 If I run the SPARQL on its own, it does pick out the observation. 如果我自己运行SPARQL,它会选择观察。 Any thoughts on why? 有什么想法吗? I am using Stardog/Stardog Studio and have also posted on their user support platform. 我正在使用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 ))
    }""" ;
] .

It looks like your constraint has two issues: 看起来您的约束有两个问题:

  1. You declare the time prefix in your SHACL, but not the base prefix. 您在SHACL中声明time前缀,但不在base前缀中声明。 You want: 你要:

     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. Your focus node is :ReferenceInterval , however the way your query is written, $this will only ever be bound to entities that :hasReferenceInterval [a :ReferenceInterval] . 您的焦点节点是:ReferenceInterval ,但是编写查询的方式, $this只会绑定到以下实体:hasReferenceInterval [a :ReferenceInterval] I rewrote the query so that ?interval is now $this as follows: 我重写了查询,以便?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 )) }""" ; 

    Adding this constraint, I was able to see a violation. 添加此约束,我能够看到违规。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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