如何通过Jena API编程读取SHACL形状图的详细信息?
Jena SHACL API 读取形状信息实现方法
注意:你示例代码里有个笔误:解析形状的静态方法是Shapes.parse(),不是Shape.parse(),先把基础加载逻辑修正,再按下面的方法取对应字段即可。
import org.apache.jena.graph.Graph; import org.apache.jena.riot.RDFDataMgr; import org.apache.jena.shacl.Shapes; import org.apache.jena.shacl.parser.Shape; Graph shapesGraph = RDFDataMgr.loadGraph("path/to/shape.ttl"); Shapes shapes = Shapes.parse(shapesGraph);
你可以通过shapes.iterator()遍历所有解析到的根形状,每个形状对象都内置了对应方法直接获取你需要的三类信息,不需要手动遍历原始RDF三元组。
1. 判断形状类型
Shape接口直接提供了类型判断方法,不用手动查rdf:type三元组:
import org.apache.jena.shacl.parser.NodeShape; for (Shape shape : shapes.getShapes()) { if (shape.isNodeShape()) { System.out.printf("形状%s是Node Shape%n", shape.getShapeNode()); } else if (shape.isPropertyShape()) { System.out.printf("形状%s是Property Shape%n", shape.getShapeNode()); } }
你示例里的根形状camo:exampleShape就是NodeShape,嵌套在sh:property块里的是PropertyShape。
2. 获取形状关联的目标类
针对NodeShape,直接调用getTargetClasses()就能拿到所有sh:targetClass定义的目标类节点:
import org.apache.jena.graph.Node; import java.util.Set; for (Shape shape : shapes.getShapes()) { if (!shape.isNodeShape()) continue; NodeShape nodeShape = (NodeShape) shape; Set<Node> targetClasses = nodeShape.getTargetClasses(); for (Node targetClass : targetClasses) { // 直接getURI()就能拿到类的完整URI,配合前缀映射可转成cm:Moving这类短名 System.out.printf("形状关联目标类:%s%n", targetClass.getURI()); } }
同系列目标获取方法还包括:
getTargetNodes():获取sh:targetNode定义的固定目标节点getTargetObjectsOf():获取sh:targetObjectsOf定义的目标节点getTargetSubjectsOf():获取sh:targetSubjectsOf定义的目标节点
3. 获取关联的属性形状及对应路径
NodeShape提供了getPropertyShapes()方法直接返回所有绑定的属性形状,每个PropertyShape可以直接取到对应的路径:
import org.apache.jena.shacl.parser.PropertyShape; import org.apache.jena.sparql.path.Path; for (Shape shape : shapes.getShapes()) { if (!shape.isNodeShape()) continue; NodeShape nodeShape = (NodeShape) shape; for (PropertyShape propShape : nodeShape.getPropertyShapes()) { if (propShape == null) continue; // 过滤空的属性形状节点 // 拿到完整路径对象,支持逆路径、复合路径等复杂场景 Path propertyPath = propShape.getPath(); // 单属性场景(比如你示例里的cm:dofNumber)可以直接取属性URI String propURI = propShape.getPredicate().getURI(); System.out.printf("属性形状对应路径:%s,属性URI:%s%n", propertyPath, propURI); // 也可以直接读属性上的约束,比如示例里的sh:minInclusive可以直接用propShape.getMinInclusive()获取 } }
如果需要读取SHACL标准外的自定义属性,可以通过shape.getShapeGraph()拿到形状对应的原始图,用常规Jena RDF API查询三元组即可。
内容的提问来源于stack exchange,提问作者user0221441
相关产品推荐
相关产品推荐

