You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何GraphDB会拒绝OGC GeoSparql SHACL约束?

为何GraphDB会拒绝OGC GeoSparql SHACL约束?

背景

GraphDB支持对传入及现有数据执行SHACL验证,OGC为GeoSPARQL标准提供了配套的SHACL shapes文件,其中包含验证通过和未通过的测试数据。

已为仓库启用SHACL和GeoSPARQL插件,使用默认命名图存储shapes,但在将shapes插入默认SHACL形状图http://rdf4j.org/schema/rdf4j#SHACLShapeGraph时,抛出以下异常:

org.eclipse.rdf4j.repository.RepositoryException: org.eclipse.rdf4j.sail.SailException: Invalid shacl constraint pattern: "^\s*$|^\s*({)(.*)(})\s*$"^^<http://www.w3.org/2001/XMLSchema#string>

未在shapes文件中找到该正则表达式,且用pyshacl处理这些shapes时无异常,怀疑是GraphDB的兼容性问题。

完整堆栈跟踪:

21:01:53.284 [repository-manager-6] INFO  c.o.rio.parallel.ParallelLoader - Using 1 threads for inference
21:01:53.350 [repository-manager-6] INFO  o.eclipse.rdf4j.sail.shacl.ShaclSail - Shapes will be persisted in: /Users/thomas/Library/Application Support/GraphDB/data/repositories/GeoSPARQL-SHACL-Test/shapes-graph/
21:01:58.359 [repositories/GeoSPARQL-SHACL-Test] INFO  o.e.r.h.s.r.n.NamespacesController - GET namespace list
21:01:58.359 [repositories/GeoSPARQL-SHACL-Test] INFO  o.e.r.h.s.r.n.NamespacesController - GET namespace list
21:01:58.363 [repositories/GeoSPARQL-SHACL-Test] INFO  o.e.r.h.s.r.TupleQueryResultView - Request for query 3392903 is finished
21:01:58.364 [repositories/GeoSPARQL-SHACL-Test] INFO  o.e.r.h.s.r.TupleQueryResultView - Request for query 3392903 is finished
21:02:15.760 [import-task-GeoSPARQL-SHACL-Test-1] ERROR c.o.f.impex.StringImportRunnableTask - Could not import file
org.eclipse.rdf4j.repository.RepositoryException: org.eclipse.rdf4j.sail.SailException: Invalid shacl constraint pattern: "^\s*$|^\s*({)(.*)(})\s*$"^^<http://www.w3.org/2001/XMLSchema#string>
    at org.eclipse.rdf4j.repository.sail.SailRepositoryConnection.addWithoutCommit(SailRepositoryConnection.java:398)
    at com.ontotext.trree.monitorRepository.MonitorRepositoryConnection.addWithoutCommit(MonitorRepositoryConnection.java:367)
    at org.eclipse.rdf4j.repository.base.AbstractRepositoryConnection.add(AbstractRepositoryConnection.java:436)
    at org.eclipse.rdf4j.repository.util.RDFInserter.addStatement(RDFInserter.java:64)
    at org.eclipse.rdf4j.repository.util.AbstractRDFInserter.handleStatement(AbstractRDFInserter.java:184)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.reportStatement(TurtleParser.java:1123)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parseObject(TurtleParser.java:454)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parseObjectList(TurtleParser.java:375)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parsePredicateObjectList(TurtleParser.java:370)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parseTriples(TurtleParser.java:335)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parseStatement(TurtleParser.java:203)
    at org.eclipse.rdf4j.rio.turtle.TurtleParser.parse(TurtleParser.java:165)
    at org.eclipse.rdf4j.repository.util.RDFLoader.loadInputStreamOrReader(RDFLoader.java:304)
    at org.eclipse.rdf4j.repository.util.RDFLoader.load(RDFLoader.java:249)
    at org.eclipse.rdf4j.repository.base.AbstractRepositoryConnection.add(AbstractRepositoryConnection.java:351)
    at com.ontotext.trree.monitorRepository.MonitorRepositoryConnection.add(MonitorRepositoryConnection.java:175)
    at com.ontotext.trree.parallel.InterruptableConnectionWrapper.add(InterruptableConnectionWrapper.java:60)
    at com.ontotext.forest.impex.ParallelAwareImporter.lambda$add$3(ParallelAwareImporter.java:96)
    at com.ontotext.forest.impex.ParallelAwareImporter.wrapInBeginCommit(ParallelAwareImporter.java:143)
    at com.ontotext.forest.impex.ParallelAwareImporter.add(ParallelAwareImporter.java:96)
    at com.ontotext.forest.impex.StringImportRunnableTask.load(StringImportRunnableTask.java:34)
    at com.ontotext.forest.impex.ImportRunnableTask.run(ImportRunnableTask.java:85)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.eclipse.rdf4j.sail.SailException: Invalid shacl constraint pattern: "^\s*$|^\s*({)(.*)(})\s*$"^^<http://www.w3.org/2001/XMLSchema#string>
    at org.eclipse.rdf4j.sail.shacl.GraphDBShaclSailConnection.validateShaclPattern(GraphDBShaclSailConnection.java:119)
    at org.eclipse.rdf4j.sail.shacl.GraphDBShaclSailConnection.addStatement(GraphDBShaclSailConnection.java:74)
    at org.eclipse.rdf4j.repository.sail.SailRepositoryConnection.addWithoutCommit(SailRepositoryConnection.java:394)
    ... 26 common frames omitted
Caused by: java.util.regex.PatternSyntaxException: Illegal repetition near index 12
^\s*$|^\s*({)(.*)(})\s*$
            ^
    at java.base/java.util.regex.Pattern.error(Unknown Source)
    at java.base/java.util.regex.Pattern.closure(Unknown Source)
    at java.base/java.util.regex.Pattern.sequence(Unknown Source)
    at java.base/java.util.regex.Pattern.expr(Unknown Source)
    at java.base/java.util.regex.Pattern.group0(Unknown Source)
    at java.base/java.util.regex.Pattern.sequence(Unknown Source)
    at java.base/java.util.regex.Pattern.expr(Unknown Source)
    at java.base/java.util.regex.Pattern.compile(Unknown Source)
    at java.base/java.util.regex.Pattern.<init>(Unknown Source)
    at java.base/java.util.regex.Pattern.compile(Unknown Source)
    at org.eclipse.rdf4j.sail.shacl.GraphDBShaclSailConnection.validateShaclPattern(GraphDBShaclSailConnection.java:116)
    ... 28 common frames omitted

问题原因

核心问题出在Java正则表达式引擎与Python正则引擎的行为差异:

  • 报错的正则^\s*$|^\s*({)(.*)(})\s*$中,{是Java正则的特殊字符,用于指定重复次数(如{2,5}),未转义的{会被视为非法重复标记,触发PatternSyntaxException。
  • pyshacl基于Python的re模块,该模块在遇到未转义的{时,若后续没有合法的重复数字/格式,会自动将其视为字面字符,因此不会报错。

你在shapes文件中找不到该正则,大概率是OGC的SHACL shapes在处理GeoSPARQL约束时,由GraphDB内部生成了这个未转义的正则表达式,或者是shapes中某个隐式的正则约束被解析后出现了这个问题。


解决方案

  1. 手动修正正则约束:
    定位OGC SHACL shapes中所有带有sh:pattern的约束,检查是否存在未转义的{或},将其替换为\{和\}(注意在Turtle等RDF格式中,反斜杠需要转义为\\,即最终写成\\{和\\})。

  2. 升级GraphDB版本:
    该问题可能是GraphDB的GeoSPARQL与SHACL插件交互的兼容性bug,尝试升级到最新版本,看官方是否已修复该问题。

  3. 临时绕过方案:
    先禁用仓库的SHACL验证,导入shapes文件后,手动修改GraphDB中对应形状的正则约束,再重新启用SHACL验证。


内容的提问来源于stack exchange,提问作者user9465104

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:42:01