Copyright © 2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
本文档定义了 SHACL 形状约束语言中与 SPARQL 相关的扩展。 SHACL 的核心部分定义了形状的基本语法以及 SHACL 支持的最常见约束组件, 而与 SPARQL 相关的扩展涵盖了通过 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 查询中(如
4.3 使用
基于 SPARQL 的约束组件进行验证中所述)。
true 表示 RDF 术语 "true"^^xsd:boolean。
false 表示 RDF 术语 "false"^^xsd:boolean。
除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释均为非规范性的。除此之外,本规范中的所有内容均为规范性的。
本文中的关键词 可以、必须、不得 和 应当 应按照 BCP 14 [RFC2119] [RFC8174] 中所述的方式解释,且仅当它们像此处所示那样全部 使用大写字母时才如此。
本文档定义了扩展 SHACL Core 的 SHACL-SPARQL 语言。 本规范描述以下对象的一致性标准:
另请参阅 SHACL 核心的一致性章节中有关良构性的讨论。
本节介绍本文档中用于为 SPARQL 查询声明命名空间前缀的机制。
形状图可以 包含命名空间前缀的声明,以便使用这些前缀缩写从同一形状图派生的 SPARQL 查询。 以下示例说明了此类前缀声明的语法。
同时具有 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 的值是前缀声明。
建议将包含使用这些前缀的形状的具名图 IRI 用作 sh:declare 值的主语。
这些 IRI 通常被声明为 sh:ShapesGraph 或 owl:Ontology 的实例,
但这不是必需的。
除其他用途外,前缀声明可由基于 SPARQL 的约束、
基于 SPARQL 的约束组件的验证器、
基于 SPARQL 的节点表达式和
基于 SPARQL 的推理规则使用。
这些节点可以使用属性 sh:prefixes 指定一组前缀映射。
可在此示例中找到
sh:prefixes 属性的用法。
sh:prefixes 的值是
IRI 或 空白节点。
SHACL 处理器将
基于 SPARQL 的约束或 验证器的 SPARQL 属性路径
sh:prefixes/(^owl:versionIRI?/owl:imports)*/sh:declare
的所有单独前缀映射(这些映射是其 值)的并集,收集为一组前缀映射。
^owl:versionIRI? 元素支持由
owl:versionIRI
导入的图,在继续沿
owl:imports 导航之前,从版本 IRI 导航到形状图 IRI。
如果这样的前缀声明集合针对 sh:prefix 的同一个 值
包含多个不同的命名空间,
那么该 形状
图是非良构的。
(请注意,SHACL 处理器可以忽略从未到达的前缀声明)。
如果 SPARQL 查询没有 sh:prefixes 的值,则系统将使用前缀声明,
这些声明来自形状
图,并且是在 owl:Ontology、sh:DataGraph、sh:ShapesGraph
或 sh:RulesGraph(它是 sh:ShapesGraph 的子类)的某个SHACL 实例上,作为 sh:declare
的值。
SHACL 处理器通过在 sh:select 的值(以及
sh:ask 和 sh:construct 等类似属性的值)前添加
所有前缀映射的 PREFIX 声明,
将其转换为 SPARQL。
每个 sh:prefix 值都会转换为 PNAME_NS,而每个
sh:namespace 值都会转换为
PREFIX 声明中的 IRIREF。
对于上面的示例形状图,SHACL-SPARQL 处理器将生成类似
PREFIX ex: <http://example.com/ns#> 的行。
如果生成的查询字符串无法解析为有效的 SPARQL 1.2 查询,SHACL-SPARQL 处理器必须产生失败。
在本文档的其余部分中,为简洁起见,可能省略了 sh:prefixes 语句。
SHACL-SPARQL 支持一种约束组件, 可用于表达基于 SPARQL SELECT 查询的限制。
约束组件 IRI:sh:SPARQLConstraintComponent
| 属性 | 摘要 |
|---|---|
sh:sparql |
声明要进行求值的 SPARQL 查询的基于 SPARQL 的约束。 |
本节的其余部分定义了基于 SPARQL 的约束的语法规则和验证过程。
本节不具有规范性。
以下示例说明了基于 SPARQL 的约束的语法。
{
"@graph": [
{
"@id": "ex:LanguageExampleShape",
"@type": "sh:NodeShape",
"sh:sparql": {
"@type": "sh:SPARQLConstraint",
"sh:message": "Values are literals with German language tag.",
"sh:prefixes": {
"@id": "http://example.com/ns#"
},
"sh:select": "\n\t\t\tSELECT $this (ex:germanLabel AS ?path) ?value\n\t\t\tWHERE {\n\t\t\t\t$this ex:germanLabel ?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"
}
}
]
}
上述形状的目标包含 ex:Country 的所有SHACL 实例。
对于这些节点(由变量 this 表示),SPARQL 查询会遍历
ex:germanLabel 的值,
并验证这些值是否为带有德语语言代码的字面量。
{
"@graph": [
{
"@id": "ex:InvalidCountry",
"@type": "ex:Country",
"ex:germanLabel": {
"@language": "en",
"@value": "Spain"
}
},
{
"@id": "ex:ValidCountry",
"@type": "ex:Country",
"ex:germanLabel": {
"@language": "de",
"@value": "Spanien"
}
}
]
}
{
"@type": "sh:ValidationReport",
"sh:conforms": {
"@type": "xsd:boolean",
"@value": "false"
},
"sh:result": {
"@type": "sh:ValidationResult",
"sh:focusNode": {
"@id": "ex:InvalidCountry"
},
"sh:resultPath": {
"@id": "ex:germanLabel"
},
"sh:resultSeverity": {
"@id": "sh:Violation"
},
"sh:sourceConstraintComponent": {
"@id": "sh:SPARQLConstraintComponent"
},
"sh:sourceShape": {
"@id": "ex:LanguageExampleShape"
},
"sh:value": {
"@language": "en",
"@value": "Spain"
}
}
}
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": "Values are literals with German language tag.",
"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 的查询都是非良构的。
本节说明 sh:SPARQLConstraintComponent 的验证器。
请注意,此验证器仅说明一种可能的实现策略,只要结果等效,
SHACL 处理器就可以选择其他方法。
$sparql 为 sh:sparql 的一个值。
如果基于 SPARQL 的约束将
true 作为属性 sh:deactivated 的值,
则不存在验证结果。
否则,执行基于 SPARQL 的约束
$sparql 指定的 SPARQL 查询,并按照3.3.1 SPARQL
约束中的预绑定变量 $this中的说明预绑定变量 this。
如果该形状是属性
形状,则在执行之前,
使用该属性形状中通过
sh:path 指定的 SHACL 属性路径
的有效 SPARQL 表面语法字符串,替换变量
PATH 出现在谓词
在三元组模式中的位置。
对于变量 failure 的绑定不是
true 的每个解,都会产生一个验证结果。
这些验证结果必须具有3.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"
}
}
]
}
声明约束组件后,即可在形状中使用其参数,如以下示例所示。
{
"@graph": [
{
"@id": "ex:CaseInsensitiveSearch",
"@type": "sh:NodeShape",
"sh:property": {
"@type": "sh:PropertyShape",
"sh:path": { "@id": "ex:code" },
"sh:pattern": "^[A-Z]{3}[0-9]{2}$",
"sh:flags": "i"
}
}
]
}
约束组件为验证引擎提供有关如何识别和验证约束
的指令,这些约束位于形状中。
通常,如果一个形状
S 具有属性 p 的一个值,并且
存在一个将 p 指定为参数的约束组件
C,而且 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 查询的约束组件。
它是 3.1 基于 SPARQL
的约束示例中示例的泛化变体。
该 SPARQL 查询包含两个常量:特定属性
ex:germanLabel 和语言标签 de,
而本示例对约束进行了泛化,使任何属性都可以使用语言标签来定义。
实际上,约束组件通过
向形状添加参数谓词来应用(例如 ex:lang "de"),SHACL-SPARQL
处理器会在执行 SELECT 验证器之前,将其预绑定到相应的 SPARQL
变量(例如 $lang)。
约束组件使这类场景能够被泛化,从而使常量通过预绑定与参数绑定。
这样便可在多个位置复用查询逻辑,而无需编写任何新的
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"
}
}
声明约束组件后(在形状图中),即可
按以下示例所示使用其参数。任何包含 ex:lang 的属性形状
都会被解释为使用
ex:LanguageConstraintComponentUsingSELECT(将 $lang 绑定到该
值)。
{
"@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": "Values are literals with language \"{$lang}\""
},
{
"@id": "ex:LanguageConstraintComponentUsingASK",
"@type": "sh:ConstraintComponent",
"rdfs:label": "Language constraint component",
"sh:labelTemplate": "Values are literals with language \"{$lang}\"",
"sh:parameter": {
"sh:datatype": {
"@id": "xsd:string"
},
"sh:description": "The language tag, e.g. \"de\".",
"sh:minLength": {
"@type": "xsd:integer",
"@value": "2"
},
"sh:name": "language",
"sh:path": {
"@id": "ex:lang"
}
},
"sh:validator": {
"@id": "ex:hasLang"
}
}
]
}
请注意,ASK 查询实现的验证条件与其 SELECT 对应项的方向“相反”:
ASK 查询针对符合约束的值节点返回 true,而
SELECT 查询返回那些不符合约束的值节点。
本节定义了基于 SPARQL 的约束组件的验证器。 请注意,此验证器仅说明一种可能的实现策略,只要结果等效, SHACL 处理器就可以选择其他方法。
第一步,必须根据 4.2.3 验证器中所述的规则选择一个验证器。 然后应用以下规则,生成一组 SPARQL 查询的解:
v,当 SPARQL ASK 查询在将 v
预绑定到变量 value 后返回
false 时,
创建一个由绑定($this,焦点节点)和
($value,v)组成的解。
令 QS 为这些解的列表。
sh:path 指定的SHACL 属性路径
的有效 SPARQL 表面语法字符串,替换变量
PATH 出现在谓词
在三元组模式中的位置。
令 QS 为执行 SPARQL 查询所产生的解。
上述 SPARQL 查询执行必须按照
3.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 的 值。
本节介绍基于 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 子句中投影
恰好一个变量。
一个 输出
节点 对于一个 选择表达式 来说,是列表 resultNodes
,其由在查询针对
焦点
图 求值时,从 SELECT 子句中投影出的(且仅此一个)
变量的绑定精确构成。
focusNode 的值会作为 SPARQL 变量 this 的值进行
预绑定。
每个作用域变量的值也会作为同名同值的 SPARQL 变量进行
预绑定。
如果作用域中某个变量的名称不是字符串字面量,则使用 "arg" + str(name)。
例如,如果变量名是 "0"^^xsd:integer,则使用 arg0。
当某个作用域变量名为 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 变量进行
预绑定。
如果作用域中某个变量的名称不是字符串字面量,则使用 "arg" + str(name)。
例如,如果变量名是 "0"^^xsd:integer,则使用 arg0。
当某个作用域变量名为 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 1.2 节点表达式 定义了 自定义列表参数 函数 作为一种声明新的节点表达式函数的机制。 这些函数可以作为其他 SHACL 节点表达式的一部分进行求值,但对于支持类似函数执行的其他引擎也可能很有用。
SPARQL 规范定义了一个 扩展点, 它使某些 SPARQL 引擎能够提供额外的 SPARQL 函数。 本节介绍一种声明式机制,使 SPARQL 处理器能够利用该扩展点将 SHACL 列表参数函数 作为 SPARQL 函数提供。
此函数将一个类作为其(唯一)参数,并返回该类的实例数量。
支持基于节点表达式的 SPARQL 函数的 SPARQL 引擎能够 处理如下所示的 SPARQL 查询:
SELECT ?class ?count
WHERE {
?class a owl:Class .
BIND (ex:instanceCount(?class) AS ?count) .
}
以下自定义列表参数函数在求值时使用“嵌套”的 SPARQL 查询。
此函数接受两个参数,并使用一个 SPARQL expr
表达式 作为其主体表达式。
在该 SPARQL 表达式中,变量 $arg0 和 $arg1 用于
访问列表参数值。
支持基于节点表达式的 SPARQL 函数的 SPARQL 引擎能够 处理如下所示的 SPARQL 查询:
SELECT ?person ?fullName
WHERE {
?person a ex:Person .
?person ex:firstName ?firstName .
?person ex:lastName ?lastName .
BIND (ex:spacedConcat(?firstName, ?lastName) AS ?fullName) .
}
以下示例使用 sh:select 节点表达式作为其主体。
此函数接受两个参数,并使用一个 SPARQL expr
表达式 作为其主体表达式。
在该 SPARQL 表达式中,变量 $arg0 和 $arg1 用于
访问列表参数值。
该函数接受一个可选参数用于匹配语言,如 sh:optional true 三元组所声明的那样。
但是请注意,sh:parameter 声明中的 SHACL 约束
不会被自动强制执行,声明的 sh:defaultValue 也不会在运行时使用。
这些主要用于文档说明。
本文档未对如何以及何时添加此类自定义 SPARQL 函数作出精确约束。
建议 SPARQL 引擎应当为任何来自所提供 SHACL 实例 的
sh:ListParameterExpressionFunction
在任意提供的 形状图
中注册函数。
如果具有相同 IRI
的函数已经注册,SHACL 引擎
必须 忽略
重新定义它的尝试,除非该函数此前是作为自定义 SPARQL 函数添加的。
在执行任何 SPARQL 查询期间,SPARQL 引擎 不得 修改已注册的 SPARQL 函数。
设 f 为 SPARQL 函数调用 的
iri,
设 args 为 Expression 参数列表。
设 function 为其定义所在 图 中
对应的自定义列表参数函数,并以 f 作为其 IRI。
对 args 中的每个 SPARQL 表达式求值,得到一个新的 节点 列表
nodesList。
若求值导致 错误,
则 SPARQL 函数调用的结果也为错误,
除非对应的 sh:parameter 为该参数声明了
sh:optional true。
在这种情况下,该参数在作用域中将是未绑定的。
设 rs 为 evalExpr(function, focusGraph, f, scope) 的 输出节点,
其中 focusGraph 是当前在 SPARQL 上下文中活动的查询图,而 scope 是
已求值参数的映射,来自 nodesList,并以参数索引作为变量名(映射键)。
如果输出节点列表 rs 恰好有一个成员,则返回该节点。
否则,或者如果求值产生一个 求值失败,
则 SPARQL 函数调用的结果为错误。
SHACL 定义了一个 RDF 词汇表,用于描述 形状——作用于一组节点的 约束 集合。 形状可以通过灵活的 目标 机制与节点关联,例如与某个类的所有实例关联。 SHACL 的一个重点领域是数据验证。 然而,用形状描述数据模式的相同原则也可用于其他目的。 SHACL 规则 在 SHACL 之上构建出一种轻量级 RDF 词汇表,用于交换可用于从现有的显式声明 RDF 三元组 推导 推理得到的 RDF 三元组 的 规则。
本节定义的 SHACL 规则
功能包含一个使用 sh:rule 和 sh:condition 等属性的通用框架,以及针对特定 规则类型
的扩展机制。
本文档定义了两种这样的规则类型:SPARQL 规则 和 三元组规则。
本节非规范性。
下面的示例说明了一个简单用例:SPARQL 规则 适用于
ex:Rectangle 类的所有实例,并通过将矩形的宽和高相乘来计算
ex:area 属性的值:
能够执行此类规则的引擎会使用与 形状 关联的
目标 声明,
以及位于 形状图 中的形状,
来确定哪些规则需要在哪些目标节点上执行。
对于那些符合任意 条件形状 的目标节点,它会执行所提供的
CONSTRUCT 查询以生成推理三元组。
在查询执行期间,变量 this 会将当前 焦点节点 作为
预绑定 变量。
SHACL
实例 的 sh:Rule,包括其子类 sh:SPARQLRule 和
sh:TripleRule,
被称为 SHACL 规则。
SHACL 具有灵活且可扩展的设计,其中可以支持多种类型的规则,
但本文档仅定义其中两种:SPARQL 规则 和 三元组规则。
每个 规则类型 都由一个 IRI 标识,该 IRI 用作它们的
rdf:type。
每种规则类型还定义了可由规则引擎实现的 执行指令。
每个 SHACL 规则 至少有一个
rdf:type
,且该类型必须是一个 IRI。
规则可以具有多个类型,例如提供可在 SPARQL 或 JavaScript 中使用的指令,具体取决于引擎的能力。
规则的创建者需要确保这些规则具有一致的语义。
如果 R 是 T 的一个 规则类型 的 SHACL 实例,
则规则 R 具有规则类型 T。
SHACL 规则处理器的输入是一组称为规则集的规则。
规则
集由一个 IRI 标识。
属性 sh:hasRule 可用于声明一个 规则集以某个给定的 规则作为
成员。
一个 图的默认
规则集是该图中所有 规则的
集合。
规则集可以使用属性 sh:includesRuleSet(传递性地)包含其他规则
集。
sh:RuleSet 的所有 SHACL
实例都有一个 IRI。
规则集可以具有
sh:hasRule 的 值,并且这些值是
规则。
一个 规则集处
sh:includesRuleSet 的 值是 IRI。
规则集 ex:RuleSet1 包含
ex:Rule1 和 ex:Rule2
(通过 ex:RuleSet2),而 ex:RuleSet2 仅包含
ex:Rule2。
属性 sh:rule 可用于
将一个 形状
(主语)
与一个 形状规则(宾语)链接起来。
sh:rule 三元组的 主语是 IRI。
SHACL 规则 可分为两类:
sh:rule 三元组 宾语的 规则。
对于作为 sh:rule 三元组 主语的 形状的所有 目标节点,都将执行形状规则。
sh:rule 谓词链接到 形状的 规则。
以下示例说明了一个 全局规则。
形状规则可以具有属性
sh:condition 的值,以指定在 目标
节点成为该规则的 焦点节点之前必须符合的 形状。
一条 规则处 sh:condition 的 值必须是良构的 形状。
如果 sh:condition 的 值
C 同时是 sh:NodeShape
和 rdfs:Class 的 SHACL 实例,那么焦点节点还必须符合
C 的 SHACL
超类中那些同时也是 sh:NodeShape 和 rdfs:Class 的 SHACL 实例的
未停用 约束。
这类似于验证期间解释 隐式
类目标的方式。
可以通过将 sh:deactivated 设置为 true 来停用规则。
规则引擎会忽略已停用的规则。
每条 规则
最多可以具有一个属性 sh:deactivated 的 值。
sh:deactivated 的 值是
xsd:boolean 字面量 true 或 false 之一。
规则可以分组到由数值标识的层中。 在执行期间,SHACL 规则引擎将遍历同一层中的所有规则, 然后再转到下一层。 数值较小的层将在数值较大的层之前执行。
每条 规则
最多可以具有一个属性 sh:layer 的 值。
规则处
sh:layer 的值是数据类型为
xsd:integer 的 字面量。
如果未指定,则规则的默认 层为 0。
示例 21提供了一个使用 sh:layer 控制规则执行顺序的示例。
规则可以按照本节中的定义,指定其在同一 层内的相对执行顺序。
每条 规则
最多可以具有一个属性 sh:order 的 值。
规则处
sh:order 的值是数据类型为
xsd:decimal 或 xsd:integer 的 字面量。
如果未指定,则默认 执行顺序为 0。
在执行 规则时,同一 层内,顺序值较大的 规则将在顺序值较小的规则之后
执行。
SHACL 规则引擎会对规则进行 迭代,允许同一规则 执行多次,直到无法再推断出更多三元组。 但是,某些规则每次执行时都可能产生新的 空白节点, 从而导致无限迭代。
规则可以使用属性 sh:runOnce 指示规则引擎,该规则
仅执行一次,并且在同一 层中的其他规则之前执行。
每条 规则
最多可以具有一个属性 sh:runOnce 的 值。
规则处
sh:runOnce 的值是 字面量,其 数据类型为
xsd:boolean。
仅运行一次的规则是一条最多执行一次的 规则(如果它是 形状规则,则对于每个形状最多执行一次)。
所有其他规则称为迭代规则。
将 true 作为其 sh:runOnce 值的 规则是
仅运行一次的规则。
SHACL Core 包含以下属性,用于派生不一定在 数据图中断言的属性值:
sh:defaultValue
定义当属性不存在其他值时
应使用哪些值。
例如,ex:childCount 的默认值可以是 0。
sh:values
定义计算属性派生值的
通用指令。
例如,矩形的 ex:area 可以通过将其
ex:width 与 ex:height 相乘来派生。
这两个属性都可以使用 节点表达式,包括
SHACL 1.2 节点
表达式中定义的节点表达式。
这两个属性只能用于为
形状所针对的 主语计算给定 谓词的
宾语。
这意味着 sh:defaultValue 和 sh:values 描述的隐式三元组
类似于规则产生的推断。
当一条 规则引用某个属性时,该规则可以合理地 预期这些隐式三元组存在。 本节说明了 规则如何确保此类派生三元组在 规则执行之前存在。
对于给定的 谓词 p,
派生
值节点是所有可以按照 SHACL 1.2 Core 的定义,
使用 sh:defaultValue 和 sh:values
在 形状图中任何使用 p 作为 sh:path 的
(未停用的)属性
形状中计算出的 值节点。
对于这些 派生值节点 v,派生
三元组是这样的 三元组:
v 是 宾语,p 是 谓词,
而 主语
是属性形状的 目标
节点。
一条 规则的预期派生三元组是该 规则处属性 sh:expectedPredicate 的所有 值所对应的 派生三元组。
所有这些最好通过一个示例来说明:
以下 数据图定义了一些 矩形实例:
SHACL 规则引擎将在处理每一层结束时从推断结果中移除派生三元组, 但规则也已推断出的三元组除外。 某些引擎可能提供保留所有派生三元组的设置,例如 当数据导出到不支持 SHACL 的系统时。
sh:RulesGraph 类
可 被用作一个图的 rdf:type,
该图通常承担 规则图 的角色。
本节其余部分非规范性。
图类型类(sh:DataGraph、sh:ShapesGraph、
sh:RulesGraph)
表示的角色并非互斥;单个图 可 被标记为多个此类之一。
规则图 可 包含引用在其他图中定义的 形状 的
sh:rule 三元组,从而允许规则独立于形状和本体定义进行管理。
SHACL 定义了属性 sh:entailment,
用于将 形状图 与
蕴涵机制 关联起来。
IRI
sh:Rules 表示 SHACL 规则蕴涵机制。
在下面的示例中,形状图向 SHACL 验证引擎表明,形状图中的 SHACL 规则需要在开始验证之前先执行。
<http://example.org/my-shapes>
a owl:Ontology ;
sh:entailment sh:Rules .
按照 SHACL 的一般策略,不支持 SHACL 规则蕴涵机制 的验证引擎 必须 在存在该 三元组 时报告 失败。 支持 SHACL 规则蕴涵机制 的验证引擎会在实际验证之前, 按照 规则执行指令 先执行规则。
有时让推理规则生成一些只在其他规则执行期间可见、但不会出现在最终推理结果中的三元组会很有用。
临时三元组 是一种推理得到的 三元组,
其推理图中包含一个 重述器,并且其
值
为 sh:tempTriple true。
临时三元组 及其 重述器 对正在执行规则的过程可见。
规则可以生成如下示例所示的此类三元组:
第一条规则计算每个 Person 的 ex:offspring 三元组,
即其(传递)子代。
第二条规则利用 ex:offspring 三元组推断每个 Person 的
ex:youngestOffspring。
最终推理只包含 ex:youngestOffspring 三元组。
所有临时三元组,即其重述器被标记为 sh:tempTriple true 的三元组,
会在推理过程结束时由 SHACL 引擎自动删除。
创建临时三元组对某些过于复杂、无法由单条规则完成的计算很有帮助。 复杂计算可以拆分为 多条 规则: 一些规则先推理出 中间 结果,而其他规则再从这些结果推导出 最终 结果。 这些中间结果只对最终结果的计算有用,在最终结果获得后就不再需要。 通过将这些中间结果标记为临时三元组,它们会在最终结果计算完成后自动移除。
SHACL 规则引擎是一种计算机过程,它 接收以下内容作为输入: 一个 数据图、一个 形状图 以及一个可选的 规则集(默认为 默认规则集,即 形状 图的默认规则集) 并且能够向 数据图添加 三元组。 规则引擎产生的新的 三元组 称为推断出的三元组。
请注意,从逻辑角度来看,一旦有 三元组被 推断出来,数据图就会被修改。 这意味着规则可以在其他三元组被推断出来后触发。 但是,在不应修改原始数据的情况下,实现可以构造一个 逻辑 数据图, 其中原始数据作为一个子图,专用的推断图作为另一个子图,并且 推断出的三元组仅添加到推断图中。
对一条 规则的执行是指
根据该 规则所属 规则
类型的 执行指令,由该规则产生 推断出的三元组的过程。
如果该 规则是
形状
规则(即它通过 sh:rule 链接到至少一个 形状),
则对于每个已链接且 未停用、并且 符合该 规则所有 未停用 条件的 形状,都会针对其每个 目标节点执行该规则。
这些 目标节点
将成为正在执行的 形状规则的 焦点
节点。
对于 形状图中的给定 规则集, 迭代是按照 8.2.6 规则排序 (sh:order)所指定的顺序,对每条单独的规则进行一次 执行, 并跳过 已停用的规则。 在一次迭代中,一条规则推断出的三元组会立即对下一条规则可见。
规则集的执行定义如下:
对于规则集中的所有层(按升序):
计算该层中所有规则的预期派生三元组
对该层中的所有仅运行一次的规则执行一次迭代
执行
对该层中的所有迭代规则执行一次迭代
当该迭代产生了新推断出的三元组时继续
删除派生三元组(规则也推断出的三元组除外)
及其具体化器
删除临时三元组及其具体化器
如果任何 规则在 执行期间报告 失败, 那么 规则集的执行也会产生 失败。
如果 规则引擎无法执行给定的 规则, 因为它不支持该 规则的任何 规则类型, 那么它会报告 失败。
超过预先配置的最大迭代 次数或产生的推断三元组数量超过预先配置的最大值后,规则引擎也可以报告失败。 这有助于防止内存不足问题和无限循环。
推断出的三元组在任何时候都不会对 形状图可见,即规则不可能 修改规则或形状的定义。
规则引擎 可 提供一个选项,用于生成额外三元组,以便跟踪
哪些规则产生了这些推理三元组。
属性 sh:sourceRule 可用于推理图中某个三元组的 重述器,从而将该三元组与 规则 关联起来。
sh:sourceRule 的值 应当 是 IRI。
下面的示例表明三元组 ex:Alice ex:friend ex:Bob 是由规则 ex:SymmetricPropertyRule
推理得到的。
<< ex:Alice ex:friend ex:Bob >> sh:sourceRule ex:SymmetricPropertyRule .
展开为 RDF 三元组后,这等价于:
_:id rdf:reifies <<( ex:Alice ex:friend ex:Bob )>> .
_:id sh:sourceRule ex:SymmetricPropertyRule .
如果规则引擎添加了这些三元组,则这些三元组不得对正在执行的规则可见。
上文描述的 一般执行算法 故意保持通用, 并为具体实现提供了很大的灵活性。 特别是,该算法在非确定性意义上运行:除非显式指定规则顺序, 否则不同执行之间的结果可能不同。 例如,当规则根据某些三元组的数量得出结论,而这些三元组又可能由其他规则产生时,就会出现这种情况。 在本文档中,产生可预测的规则排序和分层/分组的责任留给规则作者。
某些 SHACL 规则实现 可 采用不同算法来确定 一次性规则(忽略 sh:runOnce)、
规则顺序(忽略 sh:order),以及
层(忽略 sh:layer)。
例如,这可用于支持受控子集的 SHACL 规则引擎,
这些子集中可自动计算规则依赖关系。
另一个例子是能够自动防止因规则生成空白节点而导致无限循环的规则引擎。
这些实现 可 产生与仅依赖显式给定的 sh:order、sh:runOnce 和
sh:layer 值不同的结果。
某些 SHACL 规则实现 可 还报告默认算法未报告的额外 失败。
如果这最终成为 SHACL Rules 的一种变体,这里将是一个适合交叉引用正在进行中的 SRL 工作的位置。
本节定义了一种 规则类型,称为 SPARQL 规则,
其由 IRI
sh:SPARQLRule 标识。
SPARQL 规则 具有以下属性:
| 属性 | 摘要与语法规则 |
|---|---|
sh:construct |
SPARQL CONSTRUCT 查询。
SPARQL 规则 必须且只能有一个
值
对于属性 sh:construct。
sh:construct
的值是数据类型为 xsd:string 的 字面量。
|
sh:prefixes |
用于将 sh:construct 转换为 SPARQL 查询的前缀。
SPARQL 规则 可以使用属性
sh:prefixes,通过 SPARQL 查询的前缀声明
中定义的机制声明对前缀的依赖。
该机制允许用户在 sh:construct 字符串中缩写 URI。
|
由于 全局 SPARQL 规则不使用 预绑定, 因此 A. SPARQL 查询中的变量预绑定 中提到的语法限制不适用于它们。
本节定义了一种称为 三元组规则 的
规则类型,
由
IRI
sh:TripleRule 标识。
三元组规则 具有以下属性:
| 属性 | 摘要和语法规则 |
|---|---|
sh:subject |
用于计算 三元组的主体 的
节点表达式。
每个 三元组规则 必须具有最多一个
值
的 sh:subject 属性(该值必须是格式正确的
节点表达式)。
|
sh:predicate |
用于计算 三元组的谓词 的
节点表达式。
每个 三元组规则 必须具有最多一个
值
的 sh:predicate 属性(该值必须是格式正确的
节点表达式)。
|
sh:object |
用于计算 三元组的宾语 的
节点表达式。
每个 三元组规则 必须具有最多一个
值
的 sh:object 属性(该值必须是格式正确的
节点表达式)。
|
在此示例中,任何 ex:Rectangle 的实例,只要宽度等于高度,
就会获得一个额外的 rdf:type ex:Square 三元组。
在此示例中,SHACL 规则引擎将使用组合了 shnex:count 和
shnex:pathValues 的节点表达式,
为任何 ex:Person 实例推断出一个 ex:childCount 三元组。
SHACL-SPARQL 的某些功能依赖于本节所定义的变量预绑定概念。
此功能“存在风险”,并且可能会被更改(不会被移除), 以与 RDF 和 SPARQL 1.2 当前在此领域正在进行的工作保持一致。 最初作为议题 647进行讨论。
SHACL 使用的预绑定定义要求对 SPARQL 查询施加以下限制。
当 SHACL-SPARQL 处理器处理的形状图
包含使用预绑定变量执行,并且违反以下任何“必须”
限制的 SHACL-SPARQL 查询(通过 sh:ask、sh:construct 和
sh:select)时,必须报告失败。
请注意,术语可能被预绑定的变量包括变量 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 | 语法规则文本 |
|---|---|
| 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 包含多个不同命名空间,
则该 形状图 是
格式不良。
|
| 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 查询中,
唯一合法的用法是在 谓词
位置的 三元组模式 中。
|
| ConstraintComponent | 一个 基于 SPARQL 的约束组件 是一个
IRI,
并且在 形状图 中具有
sh:ConstraintComponent 的 SHACL 类型。
|
| 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。
|
| SelectExpression-syntax-prefixes | 一个 格式良好
的 选择表达式 对属性
sh:prefixes 至多有一个 值,
且该值只能是 IRI 或 空白节点。
|
| SelectExpression-query-valid | 使用 前缀处理规则 后,sh:select 的值是一个有效的
SPARQL 1.2 SELECT 查询。 |
| SelectExpression-query-output-nodes | 由 sh:select 的值派生出的 SPARQL 查询在 SELECT 子句中 投影 恰好一个变量。 |
| SPARQLExprExpression-syntax-eval | RDF 图中的一个节点
如果是一个 格式良好 的
SPARQL expr 表达式,则它必须是一个 空白节点,
该节点对谓词 sh:sparqlExpr
恰好有一个 值,
且该 值 是一个
字面量,
其 数据类型
为 xsd:string。
|
| 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 查询。 |
| rule-type | 每条 SHACL
规则都至少有一个 rdf:type,
其值是一个 IRI。
|
| RuleSet-nodeKind | sh:RuleSet 的所有 SHACL
实例都有一个 IRI。 |
| hasRule | 规则
集可以具有 sh:hasRule 的 值,并且
这些值是 规则。 |
| includesRuleSet-nodeKind | 一个 规则集处
sh:includesRuleSet 的 值是 IRI。
|
| rule | 属性 sh:rule 可用于将一个 形状(主语)
与一个 形状规则(宾语)链接起来。
sh:rule 三元组的 主语是
IRI。
|
| condition-node | 一条 规则处
sh:condition 的 值必须是良构的 形状。
|
| deactivated-maxCount | 每条 规则
最多可以具有一个属性 sh:deactivated 的 值。 |
| deactivated-in | sh:deactivated 的 值是
xsd:boolean 字面量
true 或 false 之一。
|
| rule-layer-maxCount | 每条 规则
最多可以具有一个属性 sh:layer 的 值。 |
| rule-layer-datatype | 规则处 sh:layer 的值
是数据类型为
xsd:integer 的 字面量。
|
| rule-order-maxCount | 每条 规则
最多可以具有一个属性 sh:order 的 值。 |
| rule-order-datatype | 规则处 sh:order 的值
是数据类型为
xsd:decimal 或 xsd:integer 的 字面量。
|
| run-once-maxCount | 每条 规则
最多可以具有一个属性 sh:runOnce 的 值。 |
| run-once-datatype | 规则处 sh:runOnce 的值
是 字面量,其 数据类型为
xsd:boolean。
|
| RulesGraph | sh:RulesGraph 类可以用作
一个通常充当 规则图的图的 IRI 的
rdf:type。
|
| construct-count | SPARQL 规则必须恰好具有一个属性
sh:construct 的 值。
|
| construct-datatype | sh:construct 的值
是数据类型为
xsd:string 的 字面量。
|
| TripleRule-subject | 每条 三元组规则最多只能具有一个属性
sh:subject 的 值(该值必须是良构的 节点表达式)。
|
| TripleRule-predicate | 每条 三元组规则最多只能具有一个属性
sh:predicate 的 值(该值必须是良构的 节点表达式)。
|
| TripleRule-object | 每条 三元组规则最多只能具有一个属性
sh:object 的 值(该值必须是良构的 节点表达式)。
|
| pre-binding-limitations |
SHACL 所使用的预绑定定义要求 SPARQL
查询遵守以下限制。
当 SHACL-SPARQL 处理器所操作的
形状
图
包含通过
此外,SPARQL 查询不应包含联合查询
( |
本节不具有规范性。
本附录在 [shacl12-core] 中约束 组件和目标语义的非规范性替代定义中使用了 SPARQL 1.2 的部分内容。 虽然这些定义可能有助于某些实现者,但实现 SHACL 核心语言并不要求使用 SPARQL。
使用 $ 标记的 SPARQL 变量表示在执行前已在 SPARQL 查询中预绑定的外部绑定,或者对于
$PATH,表示在执行前已在 SPARQL 查询中替换的外部绑定(如4.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 查询,在普通 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
sh:RulesGraph,见 议题
1087Referenced 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:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: