SHACL 的 NodeShape、PropertyShape、Target、Path、Focus Node、Value Node、Cardinality、Closed Shape、Severity 和 Validation Report 有什么区别?
shacl node shape property shape target path focus value node cardinality closed severity validation report differences
SHACL 用 Target 选择 Focus Node,由 NodeShape 约束节点整体、PropertyShape 沿 Path 约束 Value Node;Cardinality、Closed Shape 与 Severity 描述具体规则和结果级别,Validation Report 汇总一次验证。
十个概念快速对比
左右滑动查看完整对比 →| 概念 | 作用 | 输入/选择对象 | 输出或影响 |
|---|---|---|---|
| NodeShape | 约束节点整体 | Focus Node | 节点级结果及嵌套属性约束 |
| PropertyShape | 约束路径值 | Focus Node + Path | 针对 Value Node 的结果 |
| Target | 选择验证入口 | 类、节点、谓词等 | 产生 Focus Nodes |
| Path | 从节点导航 | RDF 属性路径 | 产生 Value Nodes |
| Focus Node | 当前被验证节点 | Target 或嵌套 shape | 出现在 resultFocusNode |
| Value Node | 被约束的值 | Path 计算结果 | 出现在 resultValue |
| Cardinality | 限制值个数 | 一组 Value Nodes | minCount/maxCount 结果 |
| Closed Shape | 限制属性集合 | Focus Node 的谓词 | 多余属性结果 |
| Severity | 标记结果严重性 | Shape/Constraint | Violation/Warning/Info 等 |
| Validation Report | 汇总一次验证 | Data Graph + Shapes Graph | conforms 与 results |
Data Graph 与 Shapes Graph 先分开
Data Graph 是待验证的 RDF 数据,Shapes Graph 保存 SHACL Shape 和约束。两者可以物理上位于同一存储,但逻辑角色不同。
Shapes Graph 本身也是 RDF,可以使用 IRI 或 Blank Node 表示 Shape。验证器不是把 Turtle 当成自定义配置文件,而是读取 RDF 图中的 SHACL 词汇。
部署时要给 Shapes Graph 版本化。只保存“验证通过”而不保存 Shape 版本、数据版本和推理配置,之后无法复现结果。
NodeShape:约束 Focus Node 本身
NodeShape 用于对一个节点整体应用约束,通常声明为 sh:NodeShape,且没有 sh:path。它可以检查 Focus Node 的类型、节点种类、取值集合、逻辑组合,也可以通过 sh:property 挂接 PropertyShape。
这里 sh:nodeKind sh:IRI 检查每个目标 Person 节点本身是否为 IRI。它不检查 Person 的某个属性值。
NodeShape 也可由另一个约束通过 sh:node 引用,使某个 Value Node 必须符合指定 Shape。引用不等于继承;SHACL Shape 之间可以组合,但没有面向对象类定义的默认继承语义。
PropertyShape:沿 Path 约束值
PropertyShape 必须有且只有一个 sh:path,其余约束作用于从 Focus Node 沿路径取得的 Value Nodes。
它可以单独拥有 Target,也可以作为 NodeShape 的 sh:property 被调用。单独声明为 sh:PropertyShape 不会自动验证所有数据;仍需 Target 或从其他 Shape 到达。
对 PropertyShape 而言,验证结果中的 Focus Node 仍是原始 Person,Value Node 是 email 值。混淆两者会让错误提示显示成“alice 不是 string”,实际失败的是 alice 的 email。
Target:哪些节点要被验证
Target 决定验证入口。SHACL Core 常见目标包括:
- sh:targetNode:指定一个或多个具体节点;
- sh:targetClass:目标类的实例;
- sh:targetSubjectsOf:拥有某谓词的 Subject;
- sh:targetObjectsOf:作为某谓词 Object 的节点。
Target 不是约束。sh:targetClass ex:Person 选择 Person 进行验证,并不产生“节点必须是 Person”的错误;若要约束值属于 Person,应使用 sh:class ex:Person 等约束组件。
Target 也不自动遍历整个图。没有被目标选择、也没有通过嵌套 Shape 到达的节点,即使数据不完整,也可能完全不出现在报告中。覆盖率审计必须检查 Target 是否选中预期数量的节点。
Focus Node:当前验证上下文
Focus Node 是某个 Shape 当前正在验证的节点。它通常来自 Target,也可能来自 sh:node、sh:qualifiedValueShape 等嵌套验证路径。
Validation Result 用 sh:focusNode 指向它。定位错误时先问:“哪一个节点被 Shape 选中?”再看 Path 和 Value,能避免把图中邻接节点误认为目标。
同一个 RDF 节点可以在多个 Shape 中成为 Focus Node,每次产生不同结果。它也可能在一个 Shape 中是 Focus Node,在另一个 PropertyShape 中成为 Value Node;角色由当前验证上下文决定,不是节点永久类型。
Path:不只是一个谓词
最简单的 sh:path ex:email 取得 Focus Node 的所有 ex:email 对象。SHACL Property Path 还支持反向路径、序列路径、替代路径,以及 zero/one/more 等路径表达。
这可从某节点反向查找所有以 ex:member 指向它的 Subject。
复杂 Path 可能返回大量值或形成图遍历,验证成本会明显增加。路径集合按 RDF 节点语义处理,不应假设数据库返回顺序稳定。Cardinality 统计的是不同 Value Nodes 的集合语义,而不是 SQL 中未去重的行数。
Path 不是 SPARQL 查询全文。SHACL Core 定义自己的 Property Path RDF 表达,与 SPARQL Property Path 相关但序列化方式不同。
Value Node:Path 的结果
对 PropertyShape,Value Nodes 是从 Focus Node 沿 Path 取得的 RDF Terms,可以是 IRI、Blank Node 或 Literal。约束组件通常逐个或整体检查这些值。
sh:datatype xsd:date 检查 Literal 的 datatype,不会把字符串自动解析并转换成日期。"2026-01-01" 与 "2026-01-01"^^xsd:date 在 RDF 中是不同项,前者不会因为词法看起来像日期就满足 datatype。
sh:class ex:Organization 检查 Value Node 是否属于相应类(结合指定 entailment),sh:nodeKind sh:IRI 检查 RDF Term 类型,sh:pattern 通常用于 Literal 的词法字符串。三者解决不同问题。
当 Path 没有任何值时,sh:datatype 不会自动报“缺失”;需要 sh:minCount 1。值约束与存在性约束必须分别写。
Cardinality:minCount 与 maxCount
sh:minCount 限制 Path 至少有多少个 Value Nodes,sh:maxCount 限制最多多少个:
这表示正好一个 birthDate,且值必须是 xsd:date。只有 min/max 不能保证数据类型;只有 datatype 也不能保证字段存在。
RDF Graph 是 Triple 集合,同一 Triple 重复载入不会产生两个值。因此 Cardinality 不用于统计重复完全相同 Triple。如果业务要记录同值的多次事件,应把事件建模为独立节点,而不是依赖重复 Triple。
sh:qualifiedMinCount/sh:qualifiedMaxCount 只统计符合某个 sh:qualifiedValueShape 的值,适合“至少两个成员是管理员”等约束,与普通总值数不同。
Closed Shape:限制未声明属性
NodeShape 设置 sh:closed true 后,Focus Node 上出现未被 Shape 的 PropertyShape Path 声明、也未列入 sh:ignoredProperties 的属性,会产生 Closed Constraint 结果。
这里允许 ex:name 和被忽略的 rdf:type,其他直接谓词可能被报告。
Closed Shape 不等于数据库禁止写入额外列。它只在验证时报告。RDF 的开放扩展生态中,过度 Closed 会把合法的来源元数据、语言标签辅助属性或新版本词汇判为错误。
复杂 Property Path 与 Closed 的“允许谓词”关系需要按规范理解;不要假设任意路径表达都会自动允许路径中所有谓词。Closed Shape 更适合边界清晰的数据交换合同。
Severity:Violation、Warning 和 Info
Shape 可以用 sh:severity 标记结果级别,标准值包括 sh:Violation、sh:Warning 和 sh:Info。未显式设置时使用规范默认 Severity。
Severity 是结果元数据,不会自动触发修复,也不等于所有工具采用相同 CI 失败阈值。有的流水线只阻止 Violation,有的要求 Warning 也为零。必须在验证器和发布流程中明确策略,并保留完整结果。
不要为了让 sh:conforms 看起来通过而把所有规则改成 Warning。严重性应根据数据使用风险定义:主键缺失可能是 Violation,推荐标签缺失可以是 Warning,迁移提示可以是 Info。
自定义 Severity IRI 可以用于业务分类,但跨工具互操作性和阈值解释要另行约定。
Validation Report:如何读结果
SHACL Validation Report 是 RDF 图,根节点类型为 sh:ValidationReport,包含 sh:conforms 和零个或多个 sh:result。
每个 Validation Result 常见字段:
- sh:focusNode:被验证节点;
- sh:resultPath:失败路径;
- sh:value:导致问题的 Value Node(适用时);
- sh:sourceShape:产生结果的 Shape;
- sh:sourceConstraintComponent:失败约束组件;
- sh:resultSeverity:严重性;
- sh:resultMessage:面向人的消息;
- sh:detail:嵌套结果(适用时)。
应用不要只显示 resultMessage。消息可能本地化或自定义,不适合作为机器错误码。机器流程应使用 sourceConstraintComponent、sourceShape、path 与 severity,UI 再渲染清晰提示。
sh:conforms 的使用还要结合工具对 Severity 的处理策略。发布闸门应检查报告、验证器配置和结果级别,而不是只抓一个布尔值后丢弃证据。
SHACL 与 OWL 的开放世界差异
OWL 用于表达本体公理并进行开放世界推理:图中没有某事实,不等于事实为假。SHACL 验证则针对当前 Data Graph 检查约束;minCount 1 会把当前看不到值的节点报告为缺失。
OWL FunctionalProperty 声明与 SHACL maxCount 1 也不同。OWL 在语义上可能推断两个值相同,而 SHACL 直接检查数据图中的 Value Nodes。SHACL 适合数据质量合同,OWL 适合知识语义与推理。
验证前可以启用 RDFS 等 entailment,让隐含类型参与 Target 或 class 检查,但是否支持、使用何种推理必须在流程中固定。不同验证器默认推理不同会产生结果差异。
Blank Node 与标识稳定性
Shapes Graph 中使用 Blank Node 定义内联 PropertyShape 很方便,但 Blank Node 标识符只在特定 RDF 作用域内有意义,序列化后可能变化。
若需要跨版本引用 Shape、抑制特定结果或做审计,给关键 Shape 分配稳定 IRI 更好。错误去重不应只依赖运行时 Blank Node ID。
Data Graph 中的 Blank Node 也可以成为 Focus/Value Node,但跨文件合并和日志定位困难。验证报告若离开原图,应附带可理解的业务键或数据定位信息。
SPARQL Constraint 何时使用
SHACL Core 已覆盖 count、datatype、class、pattern、范围、逻辑组合、唯一语言等大量约束。能用 Core 表达时优先 Core,互操作性和优化更好。
跨多个远路径聚合、复杂条件或业务关系可能需要 sh:sparql。SPARQL Constraint 通常以当前 Focus Node绑定变量执行,并返回违规结果。
自定义查询要防止性能问题和不可信 Shape 注入。Shapes Graph 若由外部用户提供,允许执行任意 SPARQL 可能造成资源消耗或访问扩展函数。生产验证应限制来源、超时和可用函数。
一套可执行的建模流程
- 先定义数据合同与业务错误,不从 SHACL 语法反推需求。
- 给每个实体类型建立 NodeShape 和明确 Target。
- 为每个字段建立 PropertyShape,分别写存在性、数量和取值约束。
- 使用稳定 IRI 标识需要审计的 Shape。
- 只有边界完全封闭时才启用 sh:closed,列出允许忽略属性。
- 给规则分配 Severity、错误码映射和多语言 Message。
- 建立通过、单项失败、多项失败、空值和推理样例。
- 保存 Shapes 版本、验证器版本、推理设置与完整 Report。
一套可执行的验收矩阵
- Target 正好选中预期节点数量,并覆盖无显式 rdf:type 的边界。
- Path 为零、一个、多个值时,min/max 结果正确。
- IRI、Blank Node、带 datatype Literal、带 language Literal 分开测试。
- 相同谓词值重复导入不被错误计为多值。
- Closed Shape 对允许、忽略和额外属性的结果正确。
- Warning/Info 与 Violation 在 CI 中按策略处理。
- 启用与禁用 entailment 的差异有明确预期。
- Validation Report 中 focus、path、value、shape 和 constraint 均可追踪。
常见误区
- 声明了 PropertyShape 却没有 Target,也没从 NodeShape 引用。
- 把 targetClass 当作 sh:class 约束。
- 用 datatype 约束代替 minCount,导致缺值不报错。
- 把 Focus Node 和 Value Node写反,错误提示指向错误对象。
- 认为 Closed Shape 会阻止 Triple 写入,而不是验证时报结果。
- 把 Warning 全部当作符合,未记录发布策略。
- 用 OWL 开放世界语义解释 SHACL 缺失值结果。
- 只保存 conforms 布尔值,不保存 Shape 版本和结果图。
结论
Target 选择 Focus Node,PropertyShape 通过 Path 找到 Value Node,NodeShape 约束节点整体,Cardinality 和 Closed Shape 分别控制值数量与属性集合,Severity 描述结果级别,Validation Report 则保存可追踪证据。把这些角色分开,SHACL 才能成为可复现的数据合同,而不是一组难以解释的错误消息。
参考资料
W3C:shaclW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:shacl ucrW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:shacl afW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:rdf11 conceptsW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:rdf11 mtW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:sparql11 queryW3C · 术语定义与技术背景 · 访问 2026-08-30
W3C:owl2 primerW3C · 术语定义与技术背景 · 访问 2026-08-30