Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本文档定义了 SHACL 形状约束语言中与 SPARQL 相关的扩展。 虽然 SHACL 的核心部分定义了形状的基本语法以及 SHACL 支持的最常见约束组件, 但与 SPARQL 相关的扩展涵盖了通过 SPARQL 扩展核心表达能力的特性。 特别是,本文档定义了如何使用 SPARQL 定义约束和约束组件, 以及基于 SPARQL 的节点表达式。
本节描述了本文档在发布时的状态。当前 W3C 出版物以及本技术报告最新修订版的列表可在 W3C 标准和草案 索引中找到。
本文档由 数据形状工作组 作为工作草案发布,并使用 推荐标准 轨道。
作为 工作草案发布并不意味着 W3C 及其成员认可该文档。
这是一个草案文档,可能随时被其他文档更新、替换或废弃。 除作为进行中的工作外,不应将本文档作为其他形式引用。
本文档由一个在 W3C 专利 政策下运行的工作组制作。 W3C 维护着一份 与该工作组交付物相关的任何专利 披露的公开列表; 该页面还包括 披露专利的说明。任何实际知悉某项专利,并认为该专利包含 必要权利要求的个人, 必须根据 W3C 专利政策第 6 节披露相关信息。
本文档受 2025 年 8 月 18 日 W3C 流程文档约束。
本规范是 SHACL 1.2 规范家族的一部分。有关它们的更详细介绍,请参见 SHACL 1.2 概述。
这些规范如下:
工作草案:
工作组说明草案:
实现者可以通过成功通过 SHACL 1.2 测试套件 的测试用例,部分检查其对上述规范的一致性水平。 但请注意,通过测试套件中的所有测试并不意味着完全符合这些 规范。 它只意味着该实现符合测试套件所测试的方面。
本文档规定了 SHACL(Shapes Constraint Language)中与 SPARQL 相关的特性。
本文档通篇使用以下术语。
本文档中定义的 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 中按该规范中的定义使用。 单个链接足以为本文档中特定术语的所有出现提供定义。
本文档中的定义是完备的,也就是说,如果本文档中没有规则使某种情况为真, 则该情况为假。
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 查询中,或者在 $PATH 的情况下
被替换到 SPARQL 查询中(如
3.3 使用
基于 SPARQL 的约束组件进行验证中所述)。
true 表示 RDF 术语 "true"^^xsd:boolean。
false 表示 RDF 术语 "false"^^xsd:boolean。
除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释均为非规范性的。除此之外,本规范中的所有内容均为规范性的。
本文档中的关键词 MAY、MUST 和 SHOULD 应按 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,且仅当它们像此处所示那样全部以 大写字母出现时才如此解释。
本文档定义了扩展 SHACL Core 的 SHACL-SPARQL 语言。 本规范描述以下对象的一致性标准:
另请参见 SHACL Core 一致性章节中关于良构性的讨论。
SHACL-SPARQL 支持一个约束组件,可用于 表达基于 SPARQL SELECT 查询的限制。
约束组件 IRI:sh:SPARQLConstraintComponent
| 属性 | 摘要 |
|---|---|
sh:sparql |
一个基于 SPARQL 的约束,声明要求值的 SPARQL 查询。 |
基于 SPARQL 的约束的语法规则和验证过程在本节其余部分中定义。
本节为非规范性内容。
以下示例说明了基于 SPARQL 的 约束的语法。
SPARQL 查询会为违反约束的变量 value 的所有绑定返回结果集
解。
对于该结果集中的每个验证结果,都会有一个
解,并应用稍后解释的映射规则。
在本示例中,每个验证结果都会将变量
this 的绑定作为 sh:focusNode,
将 ex:germanLabel 作为 sh:resultPath,并将违反约束的值作为
sh:value。
以下示例说明了一个与上述类似的场景,但使用的是属性形状。
{
"@graph": [
{
"@id": "ex:LanguageExamplePropertyShape",
"@type": "sh:PropertyShape",
"sh:path": {
"@id": "ex:germanLabel"
},
"sh:sparql": {
"@type": "sh:SPARQLConstraint",
"sh:message": "值是带有德语语言标签的字面量。",
"sh:prefixes": {
"@id": "http://example.com/ns#"
},
"sh:select": "\n\t\t\tSELECT $this ?value\n\t\t\tWHERE {\n\t\t\t\t$this $PATH ?value .\n\t\t\t\tFILTER (!isLiteral(?value) || !langMatches(lang(?value), \"de\"))\n\t\t\t}\n\t\t\t"
},
"sh:targetClass": {
"@id": "ex:Country"
}
},
{
"@id": "http://example.com/ns#",
"sh:declare": {
"@id": "_:b1"
}
}
]
}
形状可以具有属性
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:string、rdf:dirLangString、rdf:langString 或
rdf:HTML。
不应有多个 sh:message 值具有相同的语言标签,
也不应有多个数据类型为 xsd:string 的值。
基于 SPARQL 的
约束最多可以具有一个属性 sh:deactivated 的值,
并且该值要么是 true,要么是 false。
基于 SPARQL 的约束最多可以具有一个
属性 sh:severity 的值,
并且该值是一个 IRI。
在属性形状上下文中使用的
SELECT 查询
使用一个名为 PATH 的特殊变量作为形状所用路径的占位符。
在基于 SPARQL 的
约束
和基于 SELECT 的验证器的 SPARQL 查询中,
变量 PATH 的唯一合法用法是在谓词
位置出现于三元组模式中。
在任何其他位置使用变量 PATH 的查询都是非良构的。
形状 图可以包含命名空间前缀声明,以便这些前缀可用于 缩写从同一形状图派生出的 SPARQL 查询。 这种前缀声明的语法由以下示例说明。
{
"@id": "http://example.com/ns#",
"@type": "sh:ShapesGraph",
"owl:imports": {
"@id": "http://www.w3.org/ns/shacl#"
},
"sh:declare": [
{
"sh:namespace": {
"@type": "xsd:anyURI",
"@value": "http://example.com/ns#"
},
"sh:prefix": "ex"
},
{
"sh:namespace": "http://schema.org/",
"sh:prefix": "schema"
}
]
}
对于同时具有 sh:prefix 和 sh:namespace
的值的
IRI 或空白节点,
称为 前缀声明。
SHACL 词汇表包含类 sh:PrefixDeclaration,可作为此类前缀声明的类型,
尽管并不要求它们具有 rdf:type 三元组。
前缀声明对于属性
sh:prefix 恰好有一个值。
sh:prefix 的值是数据类型为
xsd:string 的字面量。
前缀声明对于属性
sh:namespace 恰好有一个值。
sh:namespace 的值是数据类型为
xsd:anyURI 或 xsd:string 的字面量。
这样的一对值指定了从前缀到命名空间的单个映射。
属性
sh:declare 的值是
前缀声明。
对于 sh:declare 的值,推荐的主语是包含使用这些前缀的形状的命名图 IRI。
这些 IRI 通常声明为 sh:ShapesGraph 或
owl: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:ShapesGraph 的
SHACL
实例处作为 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 语句。
本节解释 sh:SPARQLConstraintComponent 的验证器。
请注意,此验证器只说明一种可能的实现策略,并且
只要结果等价,SHACL 处理器可以选择其他方法。
$sparql 为 sh:sparql 的一个
值。
如果该基于 SPARQL 的约束对于属性
sh:deactivated 具有 true
作为值,
则没有验证结果。
否则,执行由基于 SPARQL 的约束 $sparql
指定的 SPARQL 查询,并按
2.3.1 SPARQL
约束中的预绑定变量 $this中所述,对变量 this 进行预绑定。
如果该形状是
属性
形状,则在执行之前,将变量 PATH
在谓词
位置出现于三元组模式时
替换为一个有效的 SPARQL 表层语法字符串,该字符串表示
在该属性形状处通过
sh:path 指定的SHACL 属性路径。
对于每个没有将 true 作为变量
failure 的绑定的
解,有一个验证结果。
这些验证结果必须具有
2.3.2 将
解绑定映射到结果属性中说明的属性值。
如果 $sparql 对 sh:severity 具有
一个值,
则该验证结果必须
将该值作为其(唯一的)sh:resultSeverity。
当且仅当某个解将
true 作为 failure 的绑定时,必须产生一个失败。
当基于 SPARQL 的约束
的 SPARQL 查询以及验证器
(属于基于 SPARQL 的约束组件)被
处理时,
SHACL-SPARQL 处理器会将变量 $this 的值
预绑定到当前焦点节点。
验证结果 节点的属性值 通过以下规则派生,来源是结果解和约束本身的值的组合。 这些规则旨在自上而下执行,以便使用第一个已绑定的值。
| 属性 | 生成规则 |
|---|---|
sh:focusNode |
|
sh:resultPath |
|
sh:value |
|
sh:resultMessage |
这些消息字面量可以通过
{?varName} 或 {$varName} 包含任何 SELECT 结果变量的名称。
如果约束基于基于 SPARQL 的
约束组件,则也可以使用该组件的参数名称。
这些 {?varName} 和 {$varName} 块应当替换为所述变量值的合适字符串表示。
|
sh:sourceConstraint |
|
基于 SPARQL 的约束提供了很大的灵活性, 但对某些人来说可能难以理解,或者会导致重复。 本节介绍基于 SPARQL 的约束 组件,作为一种抽象 SPARQL 复杂性的方式, 并用于声明类似于核心约束组件的高级可重用组件。 此类约束组件可以使用 SHACL RDF 词汇表声明,因此可以被共享和重用。
本节为非规范性内容。
以下示例演示了如何使用 SPARQL,通过
SHACL-SPARQL 语言指定新的约束组件。
该示例使用
sh:pattern 和
sh:flags,并通过
SPARQL ASK 查询验证每个值节点是否匹配给定的正则
表达式。
请注意,这只是一个示例实现,不应被视为规范性内容。
{
"@graph": [
{
"@id": "ex:hasPattern",
"@type": "sh:SPARQLAskValidator",
"sh:ask": "\n\t\tASK { \n\t\t\tFILTER (!isBlank($value) && \n\t\t\t\tIF(bound($flags), regex(str($value), $pattern, $flags), regex(str($value), $pattern)))\n\t\t}",
"sh:message": "值不匹配模式 {$pattern}"
},
{
"@id": "sh:PatternConstraintComponent",
"@type": "sh:ConstraintComponent",
"sh:parameter": [
{
"sh:path": {
"@id": "sh:pattern"
}
},
{
"sh:optional": {
"@type": "xsd:boolean",
"@value": "true"
},
"sh:path": {
"@id": "sh:flags"
}
}
],
"sh:validator": {
"@id": "ex:hasPattern"
}
}
]
}
约束组件向验证引擎提供指令,说明如何在形状中识别和验证
约束。
一般而言,如果某个形状
S 对属性 p 有一个值,并且
存在一个约束组件
C 将 p 指定为参数,并且 S 具有 C 的所有必需
参数的值,
那么这些参数值的集合(包括可选参数)声明一个
约束,并且
验证引擎使用来自 C 的合适验证器
对该约束执行验证。
在上面的示例中,sh:PatternConstraintComponent 声明了必需参数
sh:pattern、
可选参数 sh:flags,
以及一个可用于对节点形状或属性形状执行验证的
验证器。
一个基于 SPARQL 的约束组件
是一个在形状图中具有
SHACL 类型
sh:ConstraintComponent 的IRI。
本文档中声明新的约束组件的机制 仅限于基于 SPARQL 的约束组件。 不过,声明参数和验证器的一般语法也被设计为可用于 JavaScript 等其他扩展语言。
参数
通过属性 sh:parameter 声明,用于一个约束组件。
sh:parameter 的值称为参数声明。
类 sh:Parameter 可用作类型,用于参数声明,但并不要求具有这种三元组。
每个
参数声明对于属性
sh:path 恰好有一个值。
在参数声明处,
sh:path 的值是一个
IRI。
一个IRI 的局部名定义为该
IRI 末尾最长的
NCNAME,
且其前面不能紧邻该
IRI 中的第一个冒号。
参数声明的参数名定义为
sh:path 的
值的局部名。
为确保可以正确地将参数映射到 SPARQL 变量,适用以下
语法规则:
每个参数名都是有效的
SPARQL VARNAME。
参数名不得是以下之一:
this、path、PATH、value。
如果某个约束
组件中两个或更多参数声明使用
相同的参数名,则该约束组件是非良构的。
sh:optional 的值必须是数据类型为 xsd:boolean 的字面量。
一个参数声明对于属性
sh:optional 最多可以有一个值。
如果设置为 true,则该参数声明声明一个可选参数。
每个约束组件
至少有一个非可选参数。
类 sh:Parameter 被定义为
sh:PropertyShape 的SHACL 子类,
并且所有适用于属性形状的属性也可用于参数。
这包括描述性属性,例如 sh:name 和 sh:description,
也包括约束参数,例如 sh:class。
不符合
为参数声明的约束的形状是非良构的。
某些实现可以使用这些约束参数来阻止
使用无效参数值执行约束组件。
属性 sh:labelTemplate 可用于任何约束组件,
以建议如何向人类呈现约束。
sh:labelTemplate 的值是字符串(可能带有语言标签),
并称为标签模板。
本节其余部分为非规范性内容。
标签模板可以包含为约束组件声明的参数名称,
使用语法 {?varName} 或 {$varName},
其中 varName 是参数名的名称。
在显示时,这些 {?varName} 和 {$varName} 块应替换为
实际参数值。
同一主题可以有多个标签模板,但它们不应具有相同的
语言标签,
并且数据类型为 xsd:string 的模板不应超过一个。
对于每种受支持的形状类型(即属性形状或节点形状), 约束组件都会声明一个合适的验证器。 对于给定约束,验证器按以下规则从约束组件中选择, 顺序如下:
sh:nodeValidator 的某个值。sh:propertyValidator 的某个值。sh:validator 的某个值。
如果找不到合适的验证器,SHACL-SPARQL 处理器会忽略该约束。
SHACL-SPARQL 包含两类验证器,分别基于 SPARQL
SELECT(用于 sh:nodeValidator 和 sh:propertyValidator)
或 SPARQL ASK 查询(用于 sh:validator)。
具有 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。
{
"@id": "ex:LanguageConstraintComponentUsingSELECT",
"@type": "sh:ConstraintComponent",
"rdfs:label": "语言约束组件",
"sh:labelTemplate": "值是带有语言 \"{$lang}\" 的字面量",
"sh:parameter": {
"sh:datatype": {
"@id": "xsd:string"
},
"sh:description": "语言标签,例如 \"de\"。",
"sh:minLength": {
"@type": "xsd:integer",
"@value": "2"
},
"sh:name": "语言",
"sh:path": {
"@id": "ex:lang"
}
},
"sh:propertyValidator": {
"@type": "sh:SPARQLSelectValidator",
"sh:message": "值是带有语言 \"{?lang}\" 的字面量",
"sh:select": "\n\t\t\tSELECT DISTINCT $this ?value\n\t\t\tWHERE {\n\t\t\t\t$this $PATH ?value .\n\t\t\t\tFILTER (!isLiteral(?value) || !langMatches(lang(?value), $lang))\n\t\t\t}\n\t\t\t"
}
}
一旦约束组件已经声明(在形状图中),其 参数就可以按以下示例所示的方式使用。
{
"@id": "ex:LanguageExampleShape",
"@type": "sh:NodeShape",
"sh:property": [
{
"ex:lang": "de",
"sh:path": {
"@id": "ex:germanLabel"
}
},
{
"ex:lang": "en",
"sh:path": {
"@id": "ex:englishLabel"
}
}
],
"sh:targetClass": {
"@id": "ex:Country"
}
}
上述示例形状指定了这样一个条件:ex:germanLabel 的所有值
都带有语言标签 de,
而 ex:englishLabel 的所有值都以 en 作为其语言。
这些细节通过两个属性形状指定,这两个属性形状具有约束组件所需的
ex:lang 参数的值。
许多约束组件的形式是将所有值节点 分别针对某个布尔条件进行测试。 为此编写 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 查询的约束组件。
{
"@graph": [
{
"@id": "ex:hasLang",
"@type": "sh:SPARQLAskValidator",
"sh:ask": "\n\t\tASK {\n\t\t\tFILTER (isLiteral($value) && langMatches(lang($value), $lang))\n\t\t}\n\t\t",
"sh:message": "值是带有语言 \"{$lang}\" 的字面量"
},
{
"@id": "ex:LanguageConstraintComponentUsingASK",
"@type": "sh:ConstraintComponent",
"rdfs:label": "语言约束组件",
"sh:labelTemplate": "值是带有语言 \"{$lang}\" 的字面量",
"sh:parameter": {
"sh:datatype": {
"@id": "xsd:string"
},
"sh:description": "语言标签,例如 \"de\"。",
"sh:minLength": {
"@type": "xsd:integer",
"@value": "2"
},
"sh:name": "语言",
"sh:path": {
"@id": "ex:lang"
}
},
"sh:validator": {
"@id": "ex:hasLang"
}
}
]
}
请注意,ASK 查询实现的验证条件与其 SELECT 对应形式“方向相反”:
ASK 查询会为符合约束的值节点返回 true,而
SELECT 查询会返回那些不符合的值节点。
本节定义验证器,用于基于 SPARQL 的约束组件。 请注意,此验证器只说明一种可能的实现策略,并且 只要结果等价,SHACL 处理器可以选择其他方法。
第一步,必须根据 3.2.3 验证器中概述的规则选择一个验证器。 然后适用以下规则,生成一组 SPARQL 查询的解:
v,如果 SPARQL ASK 查询在将 v
预绑定到变量 value 时返回
false,
则创建一个解,由以下绑定组成:
($this,焦点节点)和
($value,v)。
令 QS 为这些解的列表。
PATH 在谓词
位置出现于三元组模式时
替换为一个有效的 SPARQL 表层语法字符串,该字符串表示
在该属性形状处通过
sh:path 指定的SHACL 属性路径。
令 QS 为执行 SPARQL 查询所产生的解。
上述 SPARQL 查询执行必须按照2.3.1 SPARQL 约束中的预绑定变量 $this中的说明,
将变量
this 预绑定。
此外,对于该约束中该约束组件的每个
参数的
值,
必须将其作为一个变量进行预绑定,该变量以
参数名作为其名称。
验证结果的生成规则
与基于 SPARQL 的约束的规则相同,
使用上面产生的解 QS。
本节扩展了使用基于 SPARQL 的约束或 约束组件来产生验证结果的一般 机制。
支持此特性的实现可以将注解属性
注入到为 SPARQL 基础的约束或约束组件的
SELECT 查询所产生的每个解而创建的验证
结果节点中。
任何此类注解属性都需要通过 sh:select 或 sh: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 变量的映射使用以下规则:
如果可以确定变量名,则 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 ; # 示例
]
] .
本节介绍基于 SPARQL 的节点表达式函数。
对 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 表达式的输出
节点是列表 resultNodes,
它正好由查询针对焦点
图求值时,从 SELECT 子句投影出的(唯一)
变量的绑定组成。
focusNode 的值会作为 SPARQL
变量 this 的值进行预绑定。
每个作用域变量的值都会作为具有相同名称和值的 SPARQL 变量进行预绑定。
当某个作用域变量名为 this 时,会产生一个失败。
evalExpr(expr, focusGraph, focusNode, scope) -> resultNodes
本节其余部分为非规范性内容。
下面是一个select 表达式用法示例,
它为属性
“full name”计算属性形状的值,方式是将 ex:firstName、一个空格和
ex:lastName 连接起来。
{
"@graph": [
{
"@id": "ex:Person-fullName",
"@type": "sh:PropertyShape",
"sh:datatype": {
"@id": "xsd:string"
},
"sh:name": "full name",
"sh:path": {
"@id": "ex:fullName"
},
"sh:values": {
"sh:prefixes": {
"@id": "http://example.com/ns"
},
"sh:select": "\n\t\t\tSELECT ?fullName\n\t\t\tWHERE {\n\t\t\t\t$this ex:firstName ?firstName .\n\t\t\t\t$this ex:lastName ?lastName .\n\t\t\t\tBIND (CONCAT(?firstName, \" \", ?lastName) AS ?fullName) .\n\t\t\t}\n\t\t"
}
},
{
"@id": "http://example.com/ns",
"@type": "owl:Ontology",
"sh:declare": {
"sh:namespace": {
"@type": "xsd:anyURI",
"@value": "http://example.com/ns#"
},
"sh:prefix": "ex"
}
}
]
}
此示例还说明了 sh:prefixes 的用法,用于在解析前将 PREFIX 声明插入到
查询开头。
请注意,该查询在执行时会将当前焦点节点预绑定到变量
this。
下面是一个select 表达式用法示例,
它计算某个形状的目标节点,使其由所有
ex:age 小于 18 的
ex:Person 实例组成。
{
"@id": "ex:ChildShape",
"@type": "sh:NodeShape",
"rdfs:comment": "此形状适用于所有 18 岁以下的人。",
"rdfs:label": "儿童形状",
"sh:targetNode": {
"sh:select": "\n\t\t\tPREFIX ex: <http://example.com/ns#>\n\t\t\tSELECT ?person\n\t\t\tWHERE {\n\t\t\t\t?person a/rdfs:subClassOf* ex:Person .\n\t\t\t\t?person ex:age ?age .\n\t\t\t\tFILTER (?age < 18) .\n\t\t\t}\n\t\t"
}
}
从以下数据图中,只有 ex:Benjamin 是目标节点。
{
"@graph": [
{
"@id": "ex:Benjamin",
"@type": "ex:Person",
"ex:age": {
"@type": "xsd:integer",
"@value": "17"
}
},
{
"@id": "ex:Bernd",
"@type": "ex:Person"
},
{
"@id": "ex:Klaus",
"@type": "ex:Person",
"ex:age": {
"@type": "xsd:integer",
"@value": "48"
}
}
]
}
对 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 表达式的输出
节点是列表
resultNodes,它正好由按照上文
定义的 select 查询的 SELECT 子句中投影出的(唯一)
变量在查询针对焦点图求值时的绑定组成。
focusNode 的值会作为 SPARQL
变量 this 的值进行预绑定。
每个作用域变量的值都会作为具有相同名称和值的 SPARQL 变量进行预绑定。
当某个作用域变量名为 this 时,会产生一个失败。
evalExpr(expr, focusGraph, focusNode, scope) -> resultNodes
本节其余部分为非规范性内容。
下面是一个SPARQL expr 表达式的用法示例, 它计算属性 “uri length”的属性形状值,即焦点节点 IRI 的长度。
{
"@id": "ex:Resource-uriLength",
"@type": "sh:PropertyShape",
"sh:datatype": {
"@id": "xsd:integer"
},
"sh:name": "uri length",
"sh:path": {
"@id": "ex:uriLength"
},
"sh:values": {
"sh:sparqlExpr": "STRLEN(STR($this))"
}
}
当应用于 URI 为 http://example.com/ns#Test 的焦点节点时,结果将是
26。
这会产生与以下变体相同的结果:
{
"@id": "ex:Resource-uriLength",
"@type": "sh:PropertyShape",
"sh:datatype": {
"@id": "xsd:integer"
},
"sh:name": "uri length",
"sh:path": {
"@id": "ex:uriLength"
},
"sh:values": {
"sh:select": "\n\t\t\tSELECT (STRLEN(STR($this)) AS ?result)\n\t\t\tWHERE {\n\t\t\t}\n\t\t"
}
}
SHACL-SPARQL 的某些特性依赖于本节所定义的变量预绑定概念。
此特性“有风险”,并且可能会被更改(不会被移除), 以便与 RDF 和 SPARQL 1.2 目前在该领域正在进行的工作保持一致。 最初作为 议题 647 讨论。
SHACL 所使用的预绑定定义要求对 SPARQL 查询施加以下限制。
当 SHACL-SPARQL 处理器所操作的形状图
包含违反任何这些“MUST”限制的 SHACL-SPARQL 查询
(通过 sh:select 和 sh:ask)时,
SHACL-SPARQL 处理器必须报告一个失败。
请注意,术语可能被预绑定的变量包括变量 this、
value(用于 ASK 查询),
以及表示使用该查询的约束
组件的参数的任何变量。
MINUS 子句VALUES 子句
AS ?var
此外,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) 的求值。
本节枚举 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:string、rdf:dirLangString、rdf:langString 或
rdf: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:anyURI 或 xsd: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:ConstraintComponent 的IRI。
|
| Parameter-predicate-count | 每个参数声明对于属性
sh:path 恰好有一个值
|
| Parameter | 在参数声明处,sh:path 的值是一个IRI。 |
| parameter-name-VARNAME | 每个参数名都是有效的 SPARQL VARNAME。 |
| parameter-name-not-in | 参数名不得是以下之一:
this、path、PATH、value。
|
| 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 查询
(通过
此外,SPARQL 查询不应包含联邦查询
( |
本节为非规范性内容。
本附录使用 SPARQL 1.2 的部分内容,为来自 [shacl12-core] 的约束 组件和目标的语义提供非规范性的替代定义。 虽然这些定义可能有助于某些实现者,但实现 SHACL Core 语言并不要求使用 SPARQL。
使用 $ 标记的 SPARQL 变量表示外部绑定,这些绑定在执行之前
预绑定到
SPARQL 查询中,或者在 $PATH 的情况下
被替换到
SPARQL 查询中(如3.3 使用
基于 SPARQL 的约束组件进行验证中所述)。
以下查询表示类目标在 SPARQL 中的潜在定义。
变量 targetClass 将被预绑定到
sh:targetClass 的给定值。
来自解中变量
this 的所有绑定都会成为焦点节点。
SELECT DISTINCT ?this # ?this 是焦点节点
WHERE {
?this rdf:type/rdfs:subClassOf* $targetClass .
}
以下查询表示主语为某谓词的目标在 SPARQL 中的潜在定义。
变量 targetSubjectsOf 将被预绑定到
sh:targetSubjectsOf 的给定值。
来自解中变量
this 的所有绑定都会成为焦点节点。
SELECT DISTINCT ?this # ?this 是焦点节点
WHERE {
?this $targetSubjectsOf ?any .
}
以下查询表示宾语为某谓词的目标在 SPARQL 中的潜在定义。
变量 targetObjectsOf 将被预绑定到
sh:targetObjectsOf 的给定值。
来自解中变量
this 的所有绑定都会成为焦点节点。
SELECT DISTINCT ?this # ?this 是焦点节点
WHERE {
?any $targetObjectsOf ?this .
}
以下查询表示 sh:class 的潜在 基于 SPARQL 的验证器。
ASK {
$value rdf:type/rdfs:subClassOf* $class .
}
以下查询表示 sh:nodeKind 的潜在 基于 SPARQL 的验证器。
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 ) )) .
}
以下查询表示 sh:minExclusive 的潜在 基于 SPARQL 的验证器。 如果值节点无法与指定范围进行比较,SPARQL 表达式会产生错误, 例如有人将字符串与整数进行比较时。 如果无法执行比较,则会有一个验证结果。 这不同于普通 SPARQL 查询等情况,在普通查询中,此类错误会静默地不产生任何结果。
ASK {
FILTER ($minExclusive < $value)
}
类似定义也可用于:
以下查询表示 sh:minLength 的潜在 基于 SPARQL 的验证器。
ASK {
FILTER (STRLEN(str($value)) >= $minLength) .
}
以下查询表示 sh:maxLength 的潜在 基于 SPARQL 的验证器。
ASK {
FILTER (STRLEN(str($value)) <= $maxLength) .
}
以下查询表示 sh:pattern 的潜在 基于 SPARQL 的验证器。
ASK {
FILTER (!isBlank($value) && IF(bound($flags), regex(str($value), $pattern, $flags), regex(str($value), $pattern)))
}
以下查询表示 sh:disjoint 的潜在 基于 SPARQL 的验证器。
SELECT DISTINCT $this ?value
WHERE {
$this $PATH ?value .
$this $disjoint ?value .
}
以下查询表示 sh:lessThan 的潜在 基于 SPARQL 的验证器。
SELECT $this ?value
WHERE {
$this $PATH ?value .
$this $lessThan ?otherValue .
BIND (?value < ?otherValue AS ?result) .
FILTER (!bound(?result) || !(?result)) .
}
以下查询表示 sh:lessThanOrEquals 的潜在 基于 SPARQL 的验证器。
SELECT $this ?value
WHERE {
$this $PATH ?value .
$this $lessThanOrEquals ?otherValue .
BIND (?value <= ?otherValue AS ?result) .
FILTER (!bound(?result) || !(?result)) .
}
本节为非规范性内容。
请注意,GRAPH 和 FROM 等 SPARQL 关键字可能会提供对
数据集中活动数据图以外图的访问。
SHACL-SPARQL 引擎应确保 SPARQL 引擎不会提供对
触发验证的用户无权访问的命名图的访问。
SHACL-SPARQL 的安全考量包括
SPARQL、
SPARQL 联邦查询
(SERVICE)以及
SHACL Core
的所有安全考量。
本节为非规范性内容。
原始 SHACL 核心规范由 RDF 数据形状工作组制作。 参见核心规范的致谢 章节以及 高级特性规范的 致谢章节。
本节为非规范性内容。
sh:SelectExpression,见议题 288
sh:SPARQLExprExpression,见议题 315
shapesGraph 和
currentShape 的支持,见议题 426
sh:severity,见议题
573sh:prefixes,系统将使用任何
sh:ShapesGraph 中声明的任意
sh:prefix/sh:namespace 对,见
议题 176
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: