首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >RDF4j Shacl验证给出了海龟和JSON的不同结果

RDF4j Shacl验证给出了海龟和JSON的不同结果
EN

Stack Overflow用户
提问于 2022-08-25 16:22:43
回答 1查看 72关注 0票数 1

我对RDF4J SHACL验证引擎有问题。

这是我使用shacl规则和示例有效负载文件作为TTL输入的代码:

代码语言:javascript
复制
String SHAPES = "rules.ttl";
String DATA = "input.ttl";

ShaclSail shaclSail = new ShaclSail(new MemoryStore());
Repository repo = new SailRepository(shaclSail);

try (RepositoryConnection connection = repo.getConnection()) {
    connection.begin();
    connection.add(new StringReader(Files.readString(Path.of(SHAPES))), RDFFormat.TURTLE, RDF4J.SHACL_SHAPE_GRAPH);
    connection.commit();

    connection.begin();
    connection.add(new StringReader(Files.readString(Path.of(DATA))), RDFFormat.TURTLE);
    connection.commit();

    connection.begin();
    connection.clear(RDF4J.SHACL_SHAPE_GRAPH);
    connection.commit();

} catch (Exception e) {
    Throwable cause = e.getCause();
    if (cause instanceof ValidationException) {
        Model validationReportModel = ((ValidationException) cause).validationReportAsModel();
        Rio.write(validationReportModel, System.out, RDFFormat.TURTLE);
    }
}

shacl规则文件如下所示:

代码语言:javascript
复制
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix shacl: <http://www.w3.org/ns/shacl#> .
​
<http://example.com/Property>
  a owl:DatatypeProperty, rdf:Property  .
​
<http://example.com/Class>
  a owl:Class .
​
<http://example.com/ClassShape>
  a <http://www.w3.org/ns/shacl#NodeShape> ;
  shacl:property <http://example.com/PropertyShape> ;
  shacl:targetClass <http://example.com/Class> .
​
<http://example.com/PropertyShape>
  a shacl:PropertyShape ;
  shacl:datatype xsd:integer ;
  shacl:maxCount 1 ;
  shacl:minCount 1 ;
  shacl:path <http://example.com/Property> .

以及输入文件:

代码语言:javascript
复制
<http://example.com/1>
  a <http://example.com/Class> ;
  <http://example.com/Property> "test" .

上面的代码段返回一个正确的数据类型冲突结果,因为<http://example.com/Property> "test" .不是规则:shacl:datatype xsd:integer ;中定义的整数。我希望这是一种行为。

但是,当我使用完全相同的数据(但使用JSON格式)时:

代码语言:javascript
复制
...
connection.add(new StringReader(Files.readString(Path.of(SHAPES))), RDFFormat.JSONLD, RDF4J.SHACL_SHAPE_GRAPH);
...
connection.add(new StringReader(Files.readString(Path.of(DATA))), RDFFormat.JSONLD);
...

使用此规则文件:

代码语言:javascript
复制
{
  "@context": {
    "id": "@id",
    "type": "@type",
    "datatype": {
      "@id": "http://www.w3.org/ns/shacl#datatype",
      "@type": "@id"
    },
    "path": {
      "@id": "http://www.w3.org/ns/shacl#path",
      "@type": "@id"
    },
    "class": {
      "@id": "http://www.w3.org/ns/shacl#class",
      "@type": "@id"
    },
    "property": {
      "@id": "http://www.w3.org/ns/shacl#property",
      "@type": "@id",
      "@container": "@set"
    },
    "targetClass": {
      "@id": "http://www.w3.org/ns/shacl#targetClass",
      "@type": "@id"
    },
    "maxCount": "http://www.w3.org/ns/shacl#maxCount",
    "minCount": "http://www.w3.org/ns/shacl#minCount",
    "PropertyShape": "http://www.w3.org/ns/shacl#PropertyShape",
    "Property": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property",
    "NodeShape": "http://www.w3.org/ns/shacl#NodeShape",
    "Class": "http://www.w3.org/2002/07/owl#Class",
    "DatatypeProperty": "http://www.w3.org/2002/07/owl#DatatypeProperty"
  },
  "@graph": [
    {
      "id": "http://example.com/Property",
      "type": [
        "DatatypeProperty",
        "Property"
      ]
    },
    {
      "id": "http://example.com/Class",
      "type": "Class"
    },
    {
      "id": "http://example.com/ClassShape",
      "type": "NodeShape",
      "property": [
        "http://example.com/PropertyShape"
      ],
      "targetClass": "http://example.com/Class"
    },
    {
      "id": "http://example.com/PropertyShape",
      "type": "PropertyShape",
      "datatype": "http://www.w3.org/2001/XMLSchema#integer",
      "maxCount": 1,
      "minCount": 1,
      "path": "http://example.com/Property"
    }
  ]
}

和内容文件:

代码语言:javascript
复制
{
    "@context": {
        "Class": "http://example.com/Class",
        "property": {
            "@id": "http://example.com/Property",
            "@type": "http://www.w3.org/2001/XMLSchema#integer"
        }
    },
    "@graph": {
        "@type": "Class",
        "@id": "http://example.com/1",
        "property": "test"
    }
}

我没有违规,这是非常令人惊讶的其他SHACL引擎线Apache或在线https://shacl.org/playground/返回正确的数据类型违规。

当我从@上下文中删除property类型时,会出现数据类型冲突:

代码语言:javascript
复制
"@type": "http://www.w3.org/2001/XMLSchema#integer"

或者将property更改为ObjectProperty:

代码语言:javascript
复制
"property": {
  "@id": "http://example.com/property1"
  ...
}

但是,例如,当我使用字符串而不是整数时,不存在数据类型冲突。

这是RDF4J中的一个bug还是预期的行为?

EN

回答 1

Stack Overflow用户

发布于 2022-08-26 09:44:08

您所观察到的是类型强制在JSON中的影响。似乎有些解析器(甚至是EasyRDF解析器)在接受类型化值时会执行额外的步骤,如果类型是已知的数字类型--他们试图将其解析为实际数字,并在输出中使用结果,而忽略了原始词法值。尝试解析"property": " 100.0 " --在将其转换为整数之前,它将修剪空格并删除.0

此解析显然可能失败,但可能无法正确地编写解析器以适应这种情况,因此在EasyRDF的情况下,这是"property": "test"的结果。

代码语言:javascript
复制
<http://example.com/1>
  a <http://example.com/Class> ;
  <http://example.com/Property> 0 .

我假设SHACL游乐场使用的解析器更智能一些,并可以将其处理为:

代码语言:javascript
复制
<http://example.com/1>
  a <http://example.com/Class> ;
  <http://example.com/Property> "test"^^<http://www.w3.org/2001/XMLSchema#integer> .

请注意,这是您在JSON中实际指定的内容:通过声明属性具有xsd:integer类型,如果不使用值对象,则它永远不可能是字符串。根据SHACL规则,结果不仅是无效的,而且在RDFS和OWL中也是矛盾的。

我没有明确的解决方案,因为我不知道RDF4J JSON解析器是否可以配置为不同的行为。然而,这些是我能想到的选择:

  • 不要使用"@type": "http://www.w3.org/2001/XMLSchema#integer"。JSON的生产者必须明确说明值的类型,甚至像"10"这样的东西也不会传递--它必须是10作为JSON中的一个数字。这仍然可以通过一个值对象(使用@type)来规避。
  • 不要忽略已解析的JSON数据;将其与输入一起保存,以便在所有SHACL处理器中都有效(但可能不是JSON的生产者所期望的)。
  • 在将数据提供给SHACL验证器之前,不要使用RDFFormat.JSONLD或使用不同的解析器。
  • 要求http://example.com/Property在SHACL中为非零,假设0确实是出现在那里的值。

附带注意:不过,SHACL游乐场使用的JSON解析器显然并不完美,因为它还将"10.5""10whatever"解析为10。它似乎使用了JavaScript的parseInt或类似的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73490841

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档