如何在SHACL验证报告中同时展示自定义sh:message与默认消息
有成熟的实现方案,不需要修改你已有的SHACL形状定义,主流SHACL验证器都支持该需求,以下是具体实现方式:
方案1:验证器原生配置(无需编码)
大部分成熟SHACL实现都预留了消息输出的开关配置,开启后可直接同时输出两种消息:
- Apache Jena SHACL 可设置
ValidationReport生成参数,开启includeAllMessages选项,验证结果的sh:resultMessage字段会自动拼接两种消息,格式为[自定义消息] 系统默认消息:[默认内容] - TopBraid SHACL API 可在创建
ValidationEngine时设置setIncludeDefaultMessages(true),自定义消息和默认消息会分别存储在结果的两个属性中,也可以配置为拼接成同一个字段输出
方案2:自定义消息生成逻辑(适配所有验证器)
如果使用的验证器没有原生支持,可以通过扩展校验逻辑实现,步骤如下:
- 加载SHACL形状图,备份所有形状的
sh:message自定义取值到自定义属性中,比如ex:customMessage - 临时删除形状图中所有的
sh:message属性,执行校验得到仅包含默认消息的原始验证报告 - 遍历验证报告结果,匹配结果对应的源形状,将备份的自定义消息追加到结果消息中,也可以作为独立字段存储
以下是Python pySHACL库的实现示例:
from pyshacl import validate import rdflib EX = rdflib.Namespace("http://example.com/") # 加载形状图并备份自定义消息 shape_graph = rdflib.Graph() shape_graph.parse("your_shapes.ttl", format="ttl") for shape_node, custom_msg in shape_graph.subject_objects(rdflib.SH.message): shape_graph.add((shape_node, EX.customMessage, custom_msg)) shape_graph.remove((shape_node, rdflib.SH.message, custom_msg)) # 执行校验获取默认消息报告 data_graph = rdflib.Graph() data_graph.parse("your_data.ttl", format="ttl") conforms, results_graph, results_text = validate( data_graph=data_graph, shacl_graph=shape_graph ) # 拼接两种消息到验证结果 for result_node in results_graph.subjects(rdflib.RDF.type, rdflib.SH.ValidationResult): source_shape = results_graph.value(result_node, rdflib.SH.sourceShape) custom_msg = shape_graph.value(source_shape, EX.customMessage) if custom_msg: default_msg = results_graph.value(result_node, rdflib.SH.resultMessage) # 拼接后覆盖原结果消息,也可新增自定义属性存储避免覆盖默认值 results_graph.set(( result_node, rdflib.SH.resultMessage, rdflib.Literal(f"自定义提示:{custom_msg} | 默认提示:{default_msg}") ))
注意事项
- 如果你需要后续程序分别解析两种消息,不要直接覆盖默认的
sh:resultMessage字段,可以给验证结果新增自定义属性比如ex:customResultMessage存储自定义消息 - 多语言场景下的自定义消息带有语言标签,拼接或存储时注意保留标签属性,避免丢失多语言信息
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

