SHACL 1.2 SPARQL 扩展

W3C 工作草案

关于本文档的更多详细信息
此版本:
https://www.w3.org/TR/2026/WD-shacl12-sparql-20260709/
最新发布版本:
https://www.w3.org/TR/shacl12-sparql/
最新编辑草案:
https://w3c.github.io/data-shapes/shacl12-sparql/
历史:
https://www.w3.org/standards/history/shacl12-sparql/
提交历史
测试套件:
https://w3c.github.io/data-shapes/data-shapes-test-suite/
最新推荐标准:
https://www.w3.org/TR/2017/REC-shacl-20170720/#part2
编辑:
(TopQuadrant, Inc.)
(JPMorgan Chase & Co.)
(Swansea University)
前编辑:
Dimitris Kontokostas
反馈:
GitHub w3c/data-shapes拉取请求新建议题未关闭议题
public-shacl@w3.org, 主题行为 [shacl12-sparql]归档

摘要

本文档定义了 SHACL 形状约束语言中与 SPARQL 相关的扩展。 虽然 SHACL 的核心部分定义了形状的基本语法以及 SHACL 支持的最常见约束组件, 但与 SPARQL 相关的扩展涵盖了通过 SPARQL 扩展核心表达能力的特性。 特别是,本文档定义了如何使用 SPARQL 定义约束和约束组件, 以及基于 SPARQL 的节点表达式。

本文档状态

本节描述了本文档在发布时的状态。当前 W3C 出版物以及本技术报告最新修订版的列表可在 W3C 标准和草案 索引中找到。

本文档由 数据形状工作组 作为工作草案发布,并使用 推荐标准 轨道

作为 工作草案发布并不意味着 W3C 及其成员认可该文档。

这是一个草案文档,可能随时被其他文档更新、替换或废弃。 除作为进行中的工作外,不应将本文档作为其他形式引用。

本文档由一个在 W3C 专利 政策下运行的工作组制作。 W3C 维护着一份 与该工作组交付物相关的任何专利 披露的公开列表; 该页面还包括 披露专利的说明。任何实际知悉某项专利,并认为该专利包含 必要权利要求的个人, 必须根据 W3C 专利政策第 6 节披露相关信息。

本文档受 2025 年 8 月 18 日 W3C 流程文档约束。

SHACL 规范

本规范是 SHACL 1.2 规范家族的一部分。有关它们的更详细介绍,请参见 SHACL 1.2 概述

这些规范如下:

工作草案:

SHACL 1.2 Core
定义 SHACL 的核心部分
SHACL 1.2 SPARQL 扩展
定义 SHACL 中与 SPARQL 相关的扩展
SHACL 1.2 节点表达式
定义用于确定 SHACL 中焦点节点的图表达式
SHACL 1.2 规则
定义 SHACL 基于规则的推理方法
SHACL 1.2 UI
定义 SHACL 用于生成用户界面
SHACL 1.2 Profiling
定义如何使用 SHACL 对数据(包括 SHACL 数据)进行剖析

工作组说明草案:

SHACL 1.2 概述
概述 SHACL 规范集
SHACL 1.2 紧凑语法
定义一种用于表达 SHACL 概念的 RDF 语法

实现者可以通过成功通过 SHACL 1.2 测试套件 的测试用例,部分检查其对上述规范的一致性水平。 但请注意,通过测试套件中的所有测试并不意味着完全符合这些 规范。 它只意味着该实现符合测试套件所测试的方面。

1. 介绍

本文档规定了 SHACL(Shapes Constraint Language)中与 SPARQL 相关的特性。

1.1 术语

本文档通篇使用以下术语。

本文档中定义的 SHACL SPARQL 扩展有时称为 SHACL-SPARQL。

链接到 RDF 1.2 Concepts and Abstract Syntax 各部分的术语在 SHACL-SPARQL 中按该规范中的定义使用。 链接到 SPARQL 1.2 Query Language 各部分的术语在 SHACL-SPARQL 中按该规范中的定义 使用。 链接到 SHACL 1.2 Core 各部分的术语在 SHACL-SPARQL 中按该规范中的定义使用。 单个链接足以为本文档中特定术语的所有出现提供定义。

本文档中的定义是完备的,也就是说,如果本文档中没有规则使某种情况为真, 则该情况为假。

基本 RDF 术语
本文档使用术语 RDF graphRDF tripleIRIliteralblank node、RDF 图中的 nodedatatypeRDF term,以及 RDF 三元组中的 subjectpredicateobject, 其定义见 RDF 1.2 Concepts and Abstract Syntax [rdf12-concepts]。
绑定、解
binding 是一个二元组(变量RDF term), 与该术语在 [sparql12-query] 中的用法一致。 solution 是一组绑定,其中每个变量必须唯一。 非正式地说,一个解通常理解为 SPARQL 查询结果表主体中的一行。

1.2 文档约定

SHACL 的语法是 RDF。 本文档中的示例使用 Turtle [rdf12-turtle]。 实践中可以使用其他 RDF 序列化,例如 RDF/XML。 读者应熟悉基本 RDF 概念 [rdf12-concepts],例如三元组, 并熟悉 SPARQL [sparql12-query]。

本文档中使用以下命名空间前缀绑定:

前缀 命名空间
owl: http://www.w3.org/2002/07/owl#
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
sh: http://www.w3.org/ns/shacl#
xsd: http://www.w3.org/2001/XMLSchema#
ex: http://example.com/ns#

本文档中使用以下 JSON-LD 上下文:

{
  "@context": {
    "owl": "http://www.w3.org/2002/07/owl#",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "sh": "http://www.w3.org/ns/shacl#",
    "xsd": "http://www.w3.org/2001/XMLSchema#",
    "ex": "http://example.com/ns#"
  }
}

请注意,定义 SHACL 词汇表本身的图的 URI 等同于 上述命名空间,即它包含 #。 对 SHACL 词汇表的引用,例如通过 owl:imports 进行引用时,应包含 #

在整篇文档中,会出现包含 Turtle 中 RDF 图的彩色编码框。 这些 Turtle 文档片段使用上面给出的前缀绑定。

SHACL 定义显示在蓝色框中:

SPARQL 或文本定义
# 此框包含 SPARQL 或文本定义。

这样的灰色框包括适用于 形状图的语法规则。

使用 $ 标记的 SPARQL 变量表示外部绑定,这些绑定在执行之前 预绑定到 SPARQL 查询中,或者在 $PATH 的情况下 被替换到 SPARQL 查询中(如 3.3 使用 基于 SPARQL 的约束组件进行验证中所述)。

true 表示 RDF 术语 "true"^^xsd:booleanfalse 表示 RDF 术语 "false"^^xsd:boolean

1.3 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释均为非规范性的。除此之外,本规范中的所有内容均为规范性的。

本文档中的关键词 MAYMUSTSHOULD 应按 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,且仅当它们像此处所示那样全部以 大写字母出现时才如此解释。

本文档定义了扩展 SHACL Core 的 SHACL-SPARQL 语言。 本规范描述以下对象的一致性标准:

另请参见 SHACL Core 一致性章节中关于良构性的讨论。

2. 基于 SPARQL 的约束

SHACL-SPARQL 支持一个约束组件,可用于 表达基于 SPARQL SELECT 查询的限制。

约束组件 IRIsh:SPARQLConstraintComponent

参数:
属性 摘要
sh:sparql 一个基于 SPARQL 的约束,声明要求值的 SPARQL 查询。

基于 SPARQL 的约束的语法规则验证过程在本节其余部分中定义。

2.1 一个基于 SPARQL 的 约束示例

本节为非规范性内容。

以下示例说明了基于 SPARQL 的 约束的语法。

SPARQL 查询会为违反约束的变量 value 的所有绑定返回结果集 。 对于该结果集中的每个验证结果,都会有一个 ,并应用稍后解释的映射规则。 在本示例中,每个验证结果都会将变量 this绑定作为 sh:focusNode, 将 ex:germanLabel 作为 sh:resultPath,并将违反约束的值作为 sh:value

以下示例说明了一个与上述类似的场景,但使用的是属性形状

2.2 基于 SPARQL 的 约束的语法

形状可以具有属性 sh:sparql 的值,并且这些值要么是 IRI,要么是空白节点 这些值称为 基于 SPARQL 的约束

基于 SPARQL 的约束对于属性 sh:select 恰好有一个sh:select 的值是数据类型为 xsd:string字面量sh:SPARQLConstraint 在 SHACL 词汇表中定义,可用作这些 约束的类型 (尽管并不要求具有类型)。 使用前缀处理规则sh:select 的值是一个 有效的 SPARQL 1.2 SELECT 查询。 sh:select 的值派生出的 SPARQL 查询会在 SELECT 子句中投影变量 this

以下两个属性与它们在形状中的用法类似:

基于 SPARQL 的 约束可以具有属性 sh:message 的值, 并且这些值是字面量,其 数据类型xsd:stringrdf:dirLangStringrdf:langStringrdf:HTML。 不应有多个 sh:message 值具有相同的语言标签, 也不应有多个数据类型为 xsd:string 的值。 基于 SPARQL 的 约束最多可以具有一个属性 sh:deactivated 的值, 并且该值要么是 true,要么是 false基于 SPARQL 的约束最多可以具有一个 属性 sh:severity 的值, 并且该值是一个 IRI

属性形状上下文中使用的 SELECT 查询 使用一个名为 PATH 的特殊变量作为形状所用路径的占位符。

基于 SPARQL 的 约束基于 SELECT 的验证器的 SPARQL 查询中, 变量 PATH 的唯一合法用法是在谓词 位置出现于三元组模式中。 在任何其他位置使用变量 PATH 的查询都是非良构的。

2.2.1 SPARQL 查询的前缀声明

形状 图可以包含命名空间前缀声明,以便这些前缀可用于 缩写从同一形状图派生出的 SPARQL 查询。 这种前缀声明的语法由以下示例说明。

对于同时具有 sh:prefixsh:namespaceIRI空白节点, 称为 前缀声明。 SHACL 词汇表包含类 sh:PrefixDeclaration,可作为此类前缀声明的类型, 尽管并不要求它们具有 rdf:type 三元组。 前缀声明对于属性 sh:prefix 恰好有一个值 sh:prefix 的值是数据类型为 xsd:string字面量 前缀声明对于属性 sh:namespace 恰好有一个值。 sh:namespace 的值是数据类型为 xsd:anyURIxsd:string字面量 这样的一对值指定了从前缀到命名空间的单个映射。 属性 sh:declare前缀声明

对于 sh:declare 的值,推荐的主语是包含使用这些前缀的形状的命名图 IRI。 这些 IRI 通常声明为 sh:ShapesGraphowl:Ontology 的实例,但这不是必需的。

前缀声明可由基于 SPARQL 的约束验证器 (属于基于 SPARQL 的约束组件), 以及由 SHACL 扩展定义的类似特性使用。 这些节点可以使用属性 sh:prefixes 来指定一组前缀映射。 sh:prefixes 属性的用法示例可见于上面的 示例

sh:prefixes 的值要么是 IRI,要么是空白节点 SHACL 处理器会收集一组前缀映射,其来源是 SPARQL 属性路径 sh:prefixes/(^owl:versionIRI?/owl:imports)*/sh:declare 中作为的所有 单个前缀映射的并集;该属性路径属于基于 SPARQL 的约束验证器^owl:versionIRI? 元素支持通过 owl:versionIRI 导入的图,会在继续跟随 owl:imports 之前,从版本 IRI 导航到形状图 IRI。 如果这样收集到的前缀声明中,对于 sh:prefix 的同一个 包含多个不同命名空间, 则该形状图非良构的。 (请注意,SHACL 处理器可以忽略从未到达的前缀声明)。

如果 SPARQL 查询没有 sh:prefixes, 则系统将使用来自形状 图中的那些前缀声明, 这些前缀声明是在 sh:ShapesGraphSHACL 实例处作为 sh:declare出现的。

SHACL 处理器会将 sh:select 的值(以及类似属性,例如 sh:ask) 转换为 SPARQL,方法是在其前面添加所有前缀映射的 PREFIX 声明。 sh:prefix 的每个值会转换为 PNAME_NS,而 sh:namespace 的每个值会转换为 PREFIX 声明中的 IRIREF。 对于上面的示例形状图,SHACL-SPARQL 处理器会生成类似 PREFIX ex: <http://example.com/ns#> 的行。 如果所得查询字符串无法解析为有效的 SPARQL 1.2 查询, SHACL-SPARQL 处理器必须产生一个失败

在本文档的其余部分中,为简洁起见,可能省略了 sh:prefixes 语句。

2.3 使用 基于 SPARQL 的约束进行验证

本节解释 sh:SPARQLConstraintComponent验证器。 请注意,此验证器只说明一种可能的实现策略,并且 只要结果等价,SHACL 处理器可以选择其他方法。

文本定义
$sparqlsh:sparql 的一个 。 如果该基于 SPARQL 的约束对于属性 sh:deactivated 具有 true 作为, 则没有验证结果。 否则,执行由基于 SPARQL 的约束 $sparql 指定的 SPARQL 查询,并按 2.3.1 SPARQL 约束中的预绑定变量 $this中所述,对变量 this 进行预绑定。 如果该形状属性 形状,则在执行之前,将变量 PATH谓词 位置出现于三元组模式替换为一个有效的 SPARQL 表层语法字符串,该字符串表示 在该属性形状处通过 sh:path 指定的SHACL 属性路径对于每个没有将 true 作为变量 failure绑定,有一个验证结果。 这些验证结果必须具有 2.3.2 将 解绑定映射到结果属性中说明的属性值。 如果 $sparqlsh:severity 具有 一个, 则该验证结果必须 将该值作为其(唯一的)sh:resultSeverity。 当且仅当某个true 作为 failure绑定时,必须产生一个失败

2.3.1 SPARQL 约束中的预绑定变量 $this

基于 SPARQL 的约束 的 SPARQL 查询以及验证器 (属于基于 SPARQL 的约束组件)被 处理时, SHACL-SPARQL 处理器会将变量 $this 的值 预绑定到当前焦点节点

2.3.2 将解绑定映射到结果属性

验证结果 节点的属性 通过以下规则派生,来源是结果解和约束本身的值的组合。 这些规则旨在自上而下执行,以便使用第一个已绑定的值。

属性 生成规则
sh:focusNode
  1. 变量 this 的绑定
sh:resultPath
  1. 变量 path 的绑定,前提是它是一个 IRI
  2. 对于由属性 形状产生的结果,是一个SHACL 属性路径,它等价于该形状的 sh:path
sh:value
  1. 变量 value 的绑定
  2. 值节点
sh:resultMessage
  1. 变量 message 的绑定
  2. 对于基于 SPARQL 的约束:该基于 SPARQL 的约束sh:message 的值。 对于基于 SPARQL 的约束组件:该 验证器 (属于基于 SPARQL 的 约束组件)的 sh:message 的值。
  3. 对于基于 SPARQL 的约束组件:该基于 SPARQL 的 约束组件sh:message 的值。
  4. 否则,应用在形状或约束处声明消息的默认机制。
这些消息字面量可以通过 {?varName}{$varName} 包含任何 SELECT 结果变量的名称。 如果约束基于基于 SPARQL 的 约束组件,则也可以使用该组件的参数名称。 这些 {?varName}{$varName}应当替换为所述变量值的合适字符串表示。
sh:sourceConstraint
  1. 基于 SPARQL 的约束, 即 sh:sparql 的值

3. 基于 SPARQL 的约束 组件

基于 SPARQL 的约束提供了很大的灵活性, 但对某些人来说可能难以理解,或者会导致重复。 本节介绍基于 SPARQL 的约束 组件,作为一种抽象 SPARQL 复杂性的方式, 并用于声明类似于核心约束组件的高级可重用组件。 此类约束组件可以使用 SHACL RDF 词汇表声明,因此可以被共享和重用。

3.1 一个 基于 SPARQL 的约束组件示例

本节为非规范性内容。

以下示例演示了如何使用 SPARQL,通过 SHACL-SPARQL 语言指定新的约束组件。 该示例使用 sh:patternsh:flags,并通过 SPARQL ASK 查询验证每个值节点是否匹配给定的正则 表达式。 请注意,这只是一个示例实现,不应被视为规范性内容。

约束组件向验证引擎提供指令,说明如何在形状中识别和验证 约束。 一般而言,如果某个形状 S 对属性 p 有一个,并且 存在一个约束组件 Cp 指定为参数,并且 S 具有 C 的所有必需 参数的值, 那么这些参数值的集合(包括可选参数)声明一个 约束,并且 验证引擎使用来自 C 的合适验证器 对该约束执行验证。 在上面的示例中,sh:PatternConstraintComponent 声明了必需参数 sh:pattern、 可选参数 sh:flags, 以及一个可用于对节点形状属性形状执行验证的 验证器

3.2 基于 SPARQL 的约束组件的语法

一个基于 SPARQL 的约束组件 是一个在形状图中具有 SHACL 类型 sh:ConstraintComponentIRI

本文档中声明新的约束组件的机制 仅限于基于 SPARQL 的约束组件。 不过,声明参数和验证器的一般语法也被设计为可用于 JavaScript 等其他扩展语言。

3.2.1 参数 声明(sh:parameter)

参数 通过属性 sh:parameter 声明,用于一个约束组件sh:parameter 的值称为参数声明。 类 sh:Parameter 可用作类型,用于参数声明,但并不要求具有这种三元组。 每个 参数声明对于属性 sh:path 恰好有一个值参数声明处, sh:path是一个 IRI

一个IRI局部名定义为该 IRI 末尾最长的 NCNAME, 且其前面不能紧邻该 IRI 中的第一个冒号。 参数声明参数名定义为 sh:path局部名。 为确保可以正确地将参数映射到 SPARQL 变量,适用以下 语法规则:

每个参数名都是有效的 SPARQL VARNAME 参数名不得是以下之一: thispathPATHvalue 如果某个约束 组件中两个或更多参数声明使用 相同的参数名,则该约束组件是非良构的。

sh:optional 的值必须是数据类型为 xsd:boolean 的字面量。 一个参数声明对于属性 sh:optional 最多可以有一个值。 如果设置为 true,则该参数声明声明一个可选参数每个约束组件 至少有一个非可选参数。

sh:Parameter 被定义为 sh:PropertyShapeSHACL 子类, 并且所有适用于属性形状的属性也可用于参数。 这包括描述性属性,例如 sh:namesh:description, 也包括约束参数,例如 sh:class符合 为参数声明的约束的形状是非良构的。 某些实现可以使用这些约束参数来阻止 使用无效参数值执行约束组件。

3.2.2 标签模板 (sh:labelTemplate)

属性 sh:labelTemplate 可用于任何约束组件, 以建议如何向人类呈现约束 sh:labelTemplate 的值是字符串(可能带有语言标签), 并称为标签模板

本节其余部分为非规范性内容。

标签模板可以包含为约束组件声明的参数名称, 使用语法 {?varName}{$varName}, 其中 varName参数名的名称。 在显示时,这些 {?varName}{$varName} 块应替换为 实际参数值。 同一主题可以有多个标签模板,但它们不应具有相同的 语言标签, 并且数据类型为 xsd:string 的模板不应超过一个。

3.2.3 验证器

对于每种受支持的形状类型(即属性形状节点形状), 约束组件都会声明一个合适的验证器。 对于给定约束,验证器按以下规则从约束组件中选择, 顺序如下:

  1. 对于节点 形状,如果存在,则使用 sh:nodeValidator 的某个值。
  2. 对于属性形状,如果存在, 则使用 sh:propertyValidator 的某个值。
  3. 否则,使用 sh:validator 的某个值。

如果找不到合适的验证器,SHACL-SPARQL 处理器会忽略该约束。

SHACL-SPARQL 包含两类验证器,分别基于 SPARQL SELECT(用于 sh:nodeValidatorsh:propertyValidator) 或 SPARQL ASK 查询(用于 sh:validator)。

3.2.3.1 基于 SELECT 的 验证器

具有 SHACL 类型 sh:SPARQLSelectValidator验证器 称为基于 SELECT 的验证器 sh:nodeValidator 的值必须是基于 SELECT 的验证器 sh:propertyValidator 的值必须是基于 SELECT 的验证器 基于 SELECT 的验证器对于属性 sh:select 恰好有一个 sh:select 的值是一个有效的 SPARQL SELECT 查询,使用前述前缀处理规则。 从 sh:select 的值派生出的 SPARQL 查询会在其 SELECT 子句中投影变量 this

本节其余部分为非规范性内容。

以下示例说明了基于 SPARQL SELECT 查询的约束组件声明。 它是2.1 一个基于 SPARQL 的约束示例中示例的 一种泛化变体。 该 SPARQL 查询包含两个常量:特定属性 ex:germanLabel 和 语言标签 de。 约束组件使这类场景可以被泛化,从而让常量通过预绑定参数关联。 这样就可以在多个地方重用查询逻辑,而不必编写任何新的 SPARQL。

一旦约束组件已经声明(在形状图中),其 参数就可以按以下示例所示的方式使用。

上述示例形状指定了这样一个条件:ex:germanLabel 的所有值 都带有语言标签 de, 而 ex:englishLabel 的所有值都以 en 作为其语言。 这些细节通过两个属性形状指定,这两个属性形状具有约束组件所需的 ex:lang 参数的值。

3.2.3.2 基于 ASK 的验证器

许多约束组件的形式是将所有值节点 分别针对某个布尔条件进行测试。 为此编写 SELECT 查询会变得繁琐,尤其是当某个约束组件可同时用于 属性形状节点 形状时。 SHACL-SPARQL 为基于 ASK 查询的验证器提供了一种替代的、更紧凑的语法。

具有 SHACL 类型 sh:SPARQLAskValidator验证器 称为基于 ASK 的验证器 sh:validator 的值必须是基于 ASK 的 验证器 基于 ASK 的验证器对于属性 sh:ask 恰好有一个值 sh:ask 的值必须是数据类型为 xsd:string 的字面量。 sh:ask 的值 必须是一个有效的 SPARQL ASK 查询,使用前述前缀 处理规则

本节其余部分为非规范性内容。

当且仅当给定值节点 (由预绑定变量 value 表示)符合约束时,ASK 查询返回 true

以下示例声明了一个使用 ASK 查询的约束组件。

请注意,ASK 查询实现的验证条件与其 SELECT 对应形式“方向相反”: ASK 查询会为符合约束的值节点返回 true,而 SELECT 查询会返回那些不符合的值节点。

3.3 使用 基于 SPARQL 的约束组件进行验证

本节定义验证器,用于基于 SPARQL 的约束组件。 请注意,此验证器只说明一种可能的实现策略,并且 只要结果等价,SHACL 处理器可以选择其他方法。

第一步,必须根据 3.2.3 验证器中概述的规则选择一个验证器。 然后适用以下规则,生成一组 SPARQL 查询的

上述 SPARQL 查询执行必须按照2.3.1 SPARQL 约束中的预绑定变量 $this中的说明, 将变量 this 预绑定。 此外,对于该约束中该约束组件的每个 参数必须将其作为一个变量进行预绑定,该变量以 参数名作为其名称。

验证结果的生成规则 与基于 SPARQL 的约束的规则相同, 使用上面产生的 QS

4. 注解属性

本节扩展了使用基于 SPARQL 的约束约束组件来产生验证结果的一般 机制

支持此特性的实现可以将注解属性 注入到为 SPARQL 基础的约束约束组件SELECT 查询所产生的每个而创建的验证 结果节点中。 任何此类注解属性都需要通过 sh:selectsh:ask 三元组主语sh:resultAnnotation声明。

sh:resultAnnotation 称为结果注解,并且要么是IRI,要么是空白 节点

结果注解具有以下属性:

属性 摘要和语法规则
sh:annotationProperty 应设置的属性。 每个结果注解对于属性 sh:annotationProperty 恰好有一个, 且该值是一个IRI
sh:annotationVarName 要从中取得注解值的 SPARQL 变量的名称。 每个结果注解对于属性 sh:annotationVarName 最多有 1 个, 且该字面量, 其数据类型xsd:string
sh:annotationValue 应作为默认值使用的常量 RDF 术语

对于 SELECT 结果集中的每个,支持注解的 SHACL 处理器会 遍历已声明的结果注解。 从结果注解到 SPARQL 变量的映射使用以下规则:

  1. 使用属性 sh:annotationVarName
  2. 如果不存在这样的, 则使用 sh:annotationProperty局部名 作为变量名。

如果可以确定变量名,则 SHACL 处理器会将给定变量的绑定 作为使用 sh:annotationProperty 指定的属性的值复制到 正在为当前产生的验证 结果中。 如果该变量在结果集中没有绑定, 则使用 sh:annotationValue, 如果存在的话。

下面是一个说明结果注解用法的示例。

ex:AnnotationExample
	a sh:NodeShape ;
	sh:targetNode ex:ExampleResource ;
	sh:sparql [   # _:b1
		sh:resultAnnotation [
			sh:annotationProperty ex:time ;
			sh:annotationVarName "time" ;
		] ;
		sh:select """
			SELECT $this ?message ?time
			WHERE {
				BIND (CONCAT("The ", "message.") AS ?message) .
				BIND (NOW() AS ?time) .
			}
			""" ;
	] .

验证会产生以下验证报告:

[	a sh:ValidationReport ;
	sh:conforms false ;
	sh:result [
		a sh:ValidationResult ;
		sh:focusNode ex:ExampleResource ;
		sh:resultMessage "The message." ;
		sh:resultSeverity sh:Violation ;
		sh:sourceConstraint _:b1 ;
		sh:sourceConstraintComponent sh:SPARQLConstraintComponent ;
		sh:sourceShape ex:AnnotationExample ;
		ex:time "2015-03-27T10:58:00"^^xsd:dateTime ;  # 示例
	]
] .

5. 基于 SPARQL 的节点表达式

本节介绍基于 SPARQL 的节点表达式函数

5.1 Select 表达式

sh:select节点 表达式称为select 表达式,其函数名sh:SelectExpression

RDF 图中的节点 如果是一个空白节点, 且对谓词 sh:select 恰好有一个, 并且该是 数据类型为 xsd:string字面量, 则该节点是一个良构select 表达式 一个良构select 表达式对于属性 sh:prefixes 最多可以有一个, 并且该值只能是IRI空白节点

使用前缀处理 规则sh:select 的值是一个有效的 SPARQL 1.2 SELECT 查询。 sh:select 的值派生出的 SPARQL 查询会在 SELECT 子句中投影 恰好一个变量。

SELECT 表达式的求值

select 表达式输出 节点是列表 resultNodes, 它正好由查询针对焦点 图求值时,从 SELECT 子句投影出的(唯一) 变量的绑定组成。 focusNode 的值会作为 SPARQL 变量 this 的值进行预绑定。 每个作用域变量的值都会作为具有相同名称和值的 SPARQL 变量进行预绑定。 当某个作用域变量名为 this 时,会产生一个失败

evalExpr(expr, focusGraph, focusNode, scope) -> resultNodes

本节其余部分为非规范性内容。

5.2 SPARQL Expr 表达式

sh:sparqlExpr节点 表达式称为SPARQL expr 表达式,其函数名sh:SPARQLExprExpression

RDF 图中的节点 如果是一个空白节点, 且对谓词 sh:sparqlExpr 恰好有一个, 并且该是 数据类型为 xsd:string字面量, 则该节点是一个良构SPARQL expr 表达式 一个良构SPARQL expr 表达式对于属性 sh:prefixes 最多可以有一个, 并且该值是一个IRI或一个空白节点

$EXPR$sh:eval, 并令 $PREFIXES$ 为使用 sh:prefixes 的值、根据前缀处理规则 得到的 SPARQL 前缀块; 则 select 定义为将 $EXPR$$PREFIXES$ 插入到如下位置所形成的字符串:

$PREFIXES$ SELECT ($EXPR$ AS ?result) WHERE {}

select 是一个有效的 SPARQL 1.2 SELECT 查询。

SPARQL EXPR 表达式的求值

SPARQL expr 表达式输出 节点是列表 resultNodes,它正好由按照上文 定义的 select 查询的 SELECT 子句中投影出的(唯一) 变量在查询针对焦点图求值时的绑定组成。 focusNode 的值会作为 SPARQL 变量 this 的值进行预绑定。 每个作用域变量的值都会作为具有相同名称和值的 SPARQL 变量进行预绑定。 当某个作用域变量名为 this 时,会产生一个失败

evalExpr(expr, focusGraph, focusNode, scope) -> resultNodes

本节其余部分为非规范性内容。

附录

A. SPARQL 查询中变量的 预绑定

SHACL-SPARQL 的某些特性依赖于本节所定义的变量预绑定概念。

(有风险特性)议题 647:向 SHACL-SPARQL 预绑定添加“有风险”声明 SPARQL

此特性“有风险”,并且可能会被更改(不会被移除), 以便与 RDF 和 SPARQL 1.2 目前在该领域正在进行的工作保持一致。 最初作为 议题 647 讨论。

SHACL 所使用的预绑定定义要求对 SPARQL 查询施加以下限制。 当 SHACL-SPARQL 处理器所操作的形状图 包含违反任何这些“MUST”限制的 SHACL-SPARQL 查询 (通过 sh:selectsh:ask)时, SHACL-SPARQL 处理器必须报告一个失败。 请注意,术语可能被预绑定的变量包括变量 thisvalue(用于 ASK 查询), 以及表示使用该查询的约束 组件参数的任何变量。

此外,SPARQL 查询不应包含联邦查询 (SERVICE)。 不允许 SERVICE 的实现必须按上文所述报告一个失败。 不过,也承认某些 SPARQL 实现将 SERVICE 关键字用作特定(通常是本地) 操作的语法,因此该关键字并未被普遍禁止。

定义:值插入

对于解映射 μ,定义 Table(μ) 为由 μ 形成的多重集。

   Table(μ) = { μ }
   Card[μ] = 1

定义值插入函数 Replace(X, μ),用于 将 X基本图 模式属性路径 表达式Graph(Var, pattern) 的每个出现 Y 替换为 join(Y, Table(μ))

定义:变量的预绑定

对带有预绑定变量 μSPARQL 查询 Q = (E, DS, QF) 的求值, 被定义为对 SPARQL 查询 Q' = (Replace(E, μ), DS, QF) 的求值。

B. SHACL 语法规则摘要

本节枚举 SHACL 的所有规范性语法规则。 本节由本规范的其他部分自动生成,并提供超链接以跳回 规则上下文不明确时所在的正文。 在形状图中违反这些规则的节点是非良构的。

语法规则 ID 语法规则文本
sparql-nodeKind 形状可以具有属性 sh:sparql 的值,并且这些值要么是IRI,要么是空白 节点
SPARQLConstraint-select-count 基于 SPARQL 的约束对于属性 sh:select 恰好有一个
SPARQLConstraint-select-datatype sh:select 的值是数据类型为 xsd:string字面量
select-query-valid 使用前缀处理规则sh:select 的值是一个有效的 SPARQL 1.2 SELECT 查询。
select-query-this sh:select 的值派生出的 SPARQL 查询会在 SELECT 子句中投影变量 this
SPARQLConstraint-message-datatype 基于 SPARQL 的约束可以具有属性 sh:message 的值, 并且这些值是字面量,其数据类型xsd:stringrdf:dirLangStringrdf:langStringrdf:HTML。 不应有多个 sh:message 值具有相同的语言标签, 也不应有多个数据类型为 xsd:string 的值。
SPARQLConstraint-deactivated-maxCount 基于 SPARQL 的约束对于属性 sh:deactivated 最多可以有一个值
SPARQLConstraint-severity 基于 SPARQL 的约束对于属性 sh:severity 最多可以有一个值, 并且该值是一个IRI
PATH-position 变量 PATH基于 SPARQL 的约束基于 SELECT 的验证器的 SPARQL 查询中的唯一合法用法, 是位于谓词 位置的三元组模式中。
prefix-count 前缀声明对于属性 sh:prefix 恰好有一个值
prefix-datatype sh:prefix 的值是数据类型为 xsd:string字面量
namespace-count 前缀声明对于属性 sh:namespace 恰好有一个值。
namespace-datatype sh:namespace 的值是数据类型为 xsd:anyURIxsd:string字面量
declare-nodeKind 属性 sh:declare前缀声明
prefixes-nodeKind sh:prefixes 的值要么是IRI,要么是空白节点
prefixes-duplicates SHACL 处理器会收集一组前缀映射,其来源是 SPARQL 属性路径 sh:prefixes/(^owl:versionIRI?/owl:imports)*/sh:declare 中作为的所有单个前缀映射的并集; 该属性路径属于基于 SPARQL 的约束验证器^owl:versionIRI? 元素支持通过 owl:versionIRI 导入的图,会在继续跟随 owl:imports 之前,从版本 IRI 导航到形状图 IRI。 如果这样收集到的前缀声明中,对于 sh:prefix 的同一个 包含多个不同命名空间, 则该形状 图非良构的。
ConstraintComponent 基于 SPARQL 的约束组件是一个在形状图中具有SHACL 类型 sh:ConstraintComponentIRI
Parameter-predicate-count 每个参数声明对于属性 sh:path 恰好有一个值
Parameter 参数声明处,sh:path是一个IRI
parameter-name-VARNAME 每个参数名都是有效的 SPARQL VARNAME
parameter-name-not-in 参数名不得是以下之一: thispathPATHvalue
parameter-name-unique 如果某个约束组件中两个或更多参数声明使用相同的参数名,则该约束组件是非良构的。
optional-datatype sh:optional 的值必须是数据类型为 xsd:boolean 的字面量。
optional-maxCount 一个参数声明对于属性 sh:optional 最多可以有一个值。
ConstraintComponent-parameter 每个约束组件至少有一个非可选参数。
Parameter-conformance 符合为参数声明的约束的形状是非良构的。
labelTemplate-datatype sh:labelTemplate 的值是字符串(可能带有语言标签)
nodeValidator-class sh:nodeValidator 的值必须是基于 SELECT 的 验证器
propertyValidator-class sh:propertyValidator 的值必须是基于 SELECT 的 验证器
SPARQLSelectValidator-select-count 基于 SELECT 的验证器对于属性 sh:select 恰好有一个
validator-class sh:validator 的值必须是基于 ASK 的 验证器
ask-count 基于 ASK 的验证器对于属性 sh:ask 恰好有一个值
ask-datatype sh:ask 的值必须是数据类型为 xsd:string 的字面量。
ask-sparql sh:ask 的值必须是一个有效的 SPARQL ASK 查询,使用前述前缀处理规则
resultAnnotation-nodeKind sh:resultAnnotation 称为结果注解,并且要么是IRI,要么是空白节点
annotationProperty 每个结果注解对于属性 sh:annotationProperty 恰好有一个, 且该值是一个IRI
annotationVarName 每个结果注解对于属性 sh:annotationVarName 最多有 1 个, 且该字面量, 其数据类型xsd:string
SelectExpression-syntax RDF 图中的节点如果是一个空白节点, 且对谓词 sh:select 恰好有一个, 并且该是 数据类型为 xsd:string字面量, 则该节点是一个良构select 表达式
SelectExpression-syntax-prefixes 一个良构select 表达式对于属性 sh:prefixes 最多可以有一个, 并且该值只能是IRI空白节点
SelectExpression-query-valid 使用前缀处理规则sh:select 的值是一个有效的 SPARQL 1.2 SELECT 查询。
SelectExpression-query-output-nodes sh:select 的值派生出的 SPARQL 查询会在 SELECT 子句中投影恰好一个变量。
SPARQLExprExpression-syntax-eval RDF 图中的节点如果是一个空白节点, 且对谓词 sh:sparqlExpr 恰好有一个, 并且该是 数据类型为 xsd:string字面量, 则该节点是一个良构SPARQL expr 表达式
SPARQLExprExpression-syntax-prefixes 一个良构SPARQL expr 表达式对于属性 sh:prefixes 最多可以有一个, 并且该值是一个IRI或一个空白节点
SPARQLExprExpression-template $EXPR$sh:eval, 并令 $PREFIXES$ 为使用 sh:prefixes 的值、根据前缀处理规则 得到的 SPARQL 前缀块; 则 select 定义为将 $EXPR$$PREFIXES$ 插入到如下位置所形成的字符串:

$PREFIXES$ SELECT ($EXPR$ AS ?result) WHERE {}

SPARQLExprExpression-query-valid select 是一个有效的 SPARQL 1.2 SELECT 查询。
pre-binding-limitations

SHACL 所使用的预绑定定义要求对 SPARQL 查询施加以下限制。 当 SHACL-SPARQL 处理器所操作的形状 图 包含违反任何这些“MUST”限制的 SHACL-SPARQL 查询 (通过 sh:selectsh:ask)时, SHACL-SPARQL 处理器必须报告一个失败。 请注意,术语可能被预绑定的变量包括变量 thisvalue(用于 ASK 查询), 以及表示使用该查询的约束组件参数的任何变量。

  • SPARQL 查询不得包含 MINUS 子句
  • SPARQL 查询不得包含提及任何可能被预绑定变量的 VALUES 子句
  • SPARQL 查询不得对任何可能被预绑定的变量使用语法形式 ​​AS ?var

此外,SPARQL 查询不应包含联邦查询 (SERVICE)。 不允许 SERVICE 的实现必须按上文所述报告一个 失败。 不过,也承认某些 SPARQL 实现将 SERVICE 关键字用作特定(通常是本地) 操作的语法,因此该关键字并未被普遍禁止。

C. SHACL 核心约束验证器的潜在 SPARQL 定义

本节为非规范性内容。

本附录使用 SPARQL 1.2 的部分内容,为来自 [shacl12-core] 的约束 组件目标的语义提供非规范性的替代定义。 虽然这些定义可能有助于某些实现者,但实现 SHACL Core 语言并不要求使用 SPARQL。

使用 $ 标记的 SPARQL 变量表示外部绑定,这些绑定在执行之前 预绑定到 SPARQL 查询中,或者在 $PATH 的情况下 被替换到 SPARQL 查询中(如3.3 使用 基于 SPARQL 的约束组件进行验证中所述)。

C.1 sh:targetClass

以下查询表示类目标在 SPARQL 中的潜在定义。 变量 targetClass 将被预绑定sh:targetClass 的给定值。 来自中变量 this 的所有绑定都会成为焦点节点。

SPARQL 中的潜在定义
SELECT DISTINCT ?this    # ?this 是焦点节点
WHERE {
	?this rdf:type/rdfs:subClassOf* $targetClass .
}

C.2 sh:targetSubjectsOf

以下查询表示主语为某谓词的目标在 SPARQL 中的潜在定义。 变量 targetSubjectsOf 将被预绑定sh:targetSubjectsOf 的给定值。 来自中变量 this 的所有绑定都会成为焦点节点。

SPARQL 中的潜在定义
SELECT DISTINCT ?this    # ?this 是焦点节点
WHERE {
	?this $targetSubjectsOf ?any .
}

C.3 sh:targetObjectsOf

以下查询表示宾语为某谓词的目标在 SPARQL 中的潜在定义。 变量 targetObjectsOf 将被预绑定sh:targetObjectsOf 的给定值。 来自中变量 this 的所有绑定都会成为焦点节点。

SPARQL 中的潜在定义
SELECT DISTINCT ?this    # ?this 是焦点节点
WHERE {
	?any $targetObjectsOf ?this .
}

C.4 sh:class

以下查询表示 sh:class 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	$value rdf:type/rdfs:subClassOf* $class .
}

C.5 sh:nodeKind

以下查询表示 sh:nodeKind 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	FILTER ((isIRI($value) && $nodeKind IN ( sh:IRI, sh:BlankNodeOrIRI, sh:IRIOrLiteral ) ) ||
		(isLiteral($value) && $nodeKind IN ( sh:Literal, sh:BlankNodeOrLiteral, sh:IRIOrLiteral ) ) ||
		(isBlank($value)   && $nodeKind IN ( sh:BlankNode, sh:BlankNodeOrIRI, sh:BlankNodeOrLiteral ) )) .
}

C.6 sh:minExclusive(等)

以下查询表示 sh:minExclusive 的潜在 基于 SPARQL 的验证器。 如果值节点无法与指定范围进行比较,SPARQL 表达式会产生错误, 例如有人将字符串与整数进行比较时。 如果无法执行比较,则会有一个验证结果。 这不同于普通 SPARQL 查询等情况,在普通查询中,此类错误会静默地不产生任何结果。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	FILTER ($minExclusive < $value)
}

类似定义也可用于:

C.7 sh:minLength

以下查询表示 sh:minLength 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	FILTER (STRLEN(str($value)) >= $minLength) .
}

C.8 sh:maxLength

以下查询表示 sh:maxLength 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	FILTER (STRLEN(str($value)) <= $maxLength) .
}

C.9 sh:pattern

以下查询表示 sh:pattern 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(必须对每个值节点 $value 求值为 true)
ASK {
	FILTER (!isBlank($value) && IF(bound($flags), regex(str($value), $pattern, $flags), regex(str($value), $pattern)))
}

C.10 sh:disjoint

以下查询表示 sh:disjoint 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(对于给定的 $PATH 必须不返回任何结果)
SELECT DISTINCT $this ?value
WHERE {
	$this $PATH ?value .
	$this $disjoint ?value .
}

C.11 sh:lessThan

以下查询表示 sh:lessThan 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(对于给定的 $PATH 必须不返回任何结果)
SELECT $this ?value
WHERE {
	$this $PATH ?value .
	$this $lessThan ?otherValue .
	BIND (?value < ?otherValue AS ?result) .
	FILTER (!bound(?result) || !(?result)) .
}

C.12 sh:lessThanOrEquals

以下查询表示 sh:lessThanOrEquals 的潜在 基于 SPARQL 的验证器。

SPARQL 中的潜在定义(对于给定的 $PATH 必须不返回任何结果)
SELECT $this ?value
WHERE {
	$this $PATH ?value .
	$this $lessThanOrEquals ?otherValue .
	BIND (?value <= ?otherValue AS ?result) .
	FILTER (!bound(?result) || !(?result)) .
}

D. 安全与隐私 考量

本节为非规范性内容。

请注意,GRAPHFROM 等 SPARQL 关键字可能会提供对 数据集中活动数据图以外图的访问。 SHACL-SPARQL 引擎应确保 SPARQL 引擎不会提供对 触发验证的用户无权访问的命名图的访问。

SHACL-SPARQL 的安全考量包括 SPARQLSPARQL 联邦查询SERVICE)以及 SHACL Core 的所有安全考量。

E. 致谢

本节为非规范性内容。

原始 SHACL 核心规范由 RDF 数据形状工作组制作。 参见核心规范的致谢 章节以及 高级特性规范的 致谢章节

F. 原始 SHACL 规范与 SHACL 1.2 SPARQL 之间的变更

本节为非规范性内容。

G. 参考文献

G.1 规范性参考文献

[owl2-syntax]
OWL 2 Web Ontology Language Structural Specification and Functional-Style Syntax (Second Edition)。Boris Motik;Peter Patel-Schneider;Bijan Parsia。W3C。2012 年 12 月 11 日。W3C 推荐标准。URL:https://www.w3.org/TR/owl2-syntax/
[rdf12-concepts]
RDF 1.2 Concepts and Abstract Data Model。Andy Seaborne;Gregg Kellogg;Olaf Hartig;Pierre-Antoine Champin。W3C。2026 年 4 月 7 日。W3C 候选推荐标准。URL:https://www.w3.org/TR/rdf12-concepts/
[rdf12-turtle]
RDF 1.2 Turtle。Gregg Kellogg;Andy Seaborne;Dominik Tomaszuk。W3C。2026 年 6 月 12 日。W3C 工作草案。URL:https://www.w3.org/TR/rdf12-turtle/
[REC-xml-names]
Namespaces in XML 1.0 (Third Edition)。 Tim Bray;Dave Hollander;Andrew Layman;Richard Tobin;Henry Thompson 等。W3C。2009 年 12 月 8 日。 W3C 推荐标准。URL:https://www.w3.org/TR/xml-names/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels。S. Bradner。IETF。1997 年 3 月。最佳当前实践。URL:https://www.rfc-editor.org/info/rfc2119/
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words。B. Leiba。IETF。2017 年 5 月。最佳当前实践。URL:https://www.rfc-editor.org/info/rfc8174/
[shacl12-core]
SHACL 1.2 Core。Holger Knublauch; Thomas Bergwinkl;Yousouf Taghzouti;Jesse Wright。W3C。2026 年 6 月 30 日。W3C 工作草案。URL:https://www.w3.org/TR/shacl12-core/
[sparql12-query]
SPARQL 1.2 Query Language。Olaf Hartig;Andy Seaborne;Ruben Taelman;Gregory Williams;Thomas Pellissier Tanon。W3C。2026 年 6 月 25 日。 W3C 工作草案。URL:https://www.w3.org/TR/sparql12-query/
[vc-data-model]
Verifiable Credentials Data Model v2.0。Ivan Herman;Michael Jones;Manu Sporny;Ted Thibodeau Jr;Gabe Cohen。W3C。 2025 年 5 月 15 日。W3C 推荐标准。URL:https://www.w3.org/TR/vc-data-model-2.0/

G.2 资料性参考文献

[sparql12-federated-query]
SPARQL 1.2 Federated Query。Ruben Taelman;Gregory Williams。W3C。2026 年 4 月 23 日。W3C 工作草案。 URL:https://www.w3.org/TR/sparql12-federated-query/