/// <summary> /// Detects the inline instances of shacl:PropertyShape and populates the shapes graph with their definition /// </summary> private static void DetectInlinePropertyShapes(RDFGraph graph, RDFShapesGraph shapesGraph) { RDFGraph inlinePropertyShapes = graph.SelectTriplesByPredicate(RDFVocabulary.SHACL.PROPERTY); foreach (RDFTriple inlinePropertyShape in inlinePropertyShapes) { //Inline property shapes are blank objects of "sh:property" constraints: //we wont find their explicit shape definition within the shapes graph. if (inlinePropertyShape.Object is RDFResource inlinePropertyShapeResource && inlinePropertyShapeResource.IsBlank && shapesGraph.SelectShape(inlinePropertyShapeResource.ToString()) == null) { RDFTriple inlinePropertyShapePath = graph.SelectTriplesBySubject(inlinePropertyShapeResource) .SelectTriplesByPredicate(RDFVocabulary.SHACL.PATH) .FirstOrDefault(); if (inlinePropertyShapePath != null && inlinePropertyShapePath.Object is RDFResource) { RDFPropertyShape propertyShape = new RDFPropertyShape(inlinePropertyShapeResource, (RDFResource)inlinePropertyShapePath.Object); DetectShapeTargets(graph, propertyShape); DetectShapeAttributes(graph, propertyShape); DetectShapeNonValidatingAttributes(graph, propertyShape); DetectShapeConstraints(graph, propertyShape); shapesGraph.AddShape(propertyShape); } } } }
/// <summary> /// Detects the typed instances of shacl:PropertyShape and populates the shapes graph with their definition /// </summary> private static void DetectTypedPropertyShapes(RDFGraph graph, RDFShapesGraph shapesGraph) { RDFGraph declaredPropertyShapes = graph.SelectTriplesByPredicate(RDFVocabulary.RDF.TYPE) .SelectTriplesByObject(RDFVocabulary.SHACL.PROPERTY_SHAPE); foreach (RDFTriple declaredPropertyShape in declaredPropertyShapes) { RDFTriple declaredPropertyShapePath = graph.SelectTriplesBySubject((RDFResource)declaredPropertyShape.Subject) .SelectTriplesByPredicate(RDFVocabulary.SHACL.PATH) .FirstOrDefault(); if (declaredPropertyShapePath != null && declaredPropertyShapePath.Object is RDFResource) { RDFPropertyShape propertyShape = new RDFPropertyShape((RDFResource)declaredPropertyShape.Subject, (RDFResource)declaredPropertyShapePath.Object); DetectShapeTargets(graph, propertyShape); DetectShapeAttributes(graph, propertyShape); DetectShapeNonValidatingAttributes(graph, propertyShape); DetectShapeConstraints(graph, propertyShape); shapesGraph.AddShape(propertyShape); } } }
private static RDFShape ParseShapeType(DataRow shapesRow) { RDFShape shape = null; //sh:NodeShape if (!shapesRow.IsNull("?NSHAPE")) { shape = new RDFNodeShape(new RDFResource(shapesRow.Field <string>("?NSHAPE"))); } //sh:PropertyShape else if (!shapesRow.IsNull("?PSHAPE") && !shapesRow.IsNull("?PATH")) { shape = new RDFPropertyShape(new RDFResource(shapesRow.Field <string>("?PSHAPE")), new RDFResource(shapesRow.Field <string>("?PATH"))); //sh:description if (!shapesRow.IsNull("?DESCRIPTION")) { RDFPatternMember description = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?DESCRIPTION")); if (description is RDFLiteral) { ((RDFPropertyShape)shape).AddDescription((RDFLiteral)description); } } //sh:name if (!shapesRow.IsNull("?NAME")) { RDFPatternMember name = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?NAME")); if (name is RDFLiteral) { ((RDFPropertyShape)shape).AddName((RDFLiteral)name); } } //sh:group if (!shapesRow.IsNull("?GROUP")) { RDFPatternMember group = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?GROUP")); if (group is RDFResource) { ((RDFPropertyShape)shape).SetGroup((RDFResource)group); } } //sh:order if (!shapesRow.IsNull("?ORDER")) { RDFPatternMember order = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?ORDER")); if (order is RDFTypedLiteral && ((RDFTypedLiteral)order).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { ((RDFPropertyShape)shape).SetOrder(int.Parse(((RDFTypedLiteral)order).Value)); } } } return(shape); }
/// <summary> /// Detects the non validating attributes of the given property shape /// </summary> private static void DetectShapeNonValidatingAttributes(RDFGraph graph, RDFPropertyShape propertyShape) { RDFGraph shapeDefinition = graph.SelectTriplesBySubject(propertyShape); //sh:description (accepted occurrences: N) RDFGraph shapeDescriptions = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.DESCRIPTION); foreach (RDFTriple shapeDescription in shapeDescriptions.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPL)) { propertyShape.AddDescription((RDFLiteral)shapeDescription.Object); } //sh:name (accepted occurrences: N) RDFGraph shapeNames = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.NAME); foreach (RDFTriple shapeName in shapeNames.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPL)) { propertyShape.AddName((RDFLiteral)shapeName.Object); } //sh:group (accepted occurrences: 1) RDFTriple shapeGroup = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.GROUP).FirstOrDefault(); if (shapeGroup != null) { if (shapeGroup.Object is RDFResource) { propertyShape.SetGroup((RDFResource)shapeGroup.Object); } } //sh:order (accepted occurrences: 1) RDFTriple shapeOrder = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.ORDER).FirstOrDefault(); if (shapeOrder != null) { if (shapeOrder.Object is RDFTypedLiteral shapeOrderLiteral && shapeOrderLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { propertyShape.SetOrder(int.Parse(shapeOrderLiteral.Value)); } } }
/// <summary> /// Evaluates this constraint against the given data graph /// </summary> internal override RDFValidationReport ValidateConstraint(RDFShapesGraph shapesGraph, RDFGraph dataGraph, RDFShape shape, RDFPatternMember focusNode, List <RDFPatternMember> valueNodes) { RDFValidationReport report = new RDFValidationReport(); #region Evaluation if (this.Closed) { //Extend ignored properties with paths of property constraints List <RDFResource> allowedProperties = new List <RDFResource>(this.IgnoredProperties.Values); IEnumerable <RDFPropertyConstraint> propertyConstraints = shape.Constraints.OfType <RDFPropertyConstraint>(); foreach (RDFPropertyConstraint propertyConstraint in propertyConstraints) { RDFPropertyShape propertyShape = shapesGraph.SelectShape(propertyConstraint.PropertyShapeUri.ToString()) as RDFPropertyShape; if (propertyShape != null) { allowedProperties.Add(propertyShape.Path); } } //Detect unallowed predicates foreach (RDFPatternMember valueNode in valueNodes) { if (valueNode is RDFResource valueNodeResource) { RDFGraph valuenodeResourceGraph = dataGraph.SelectTriplesBySubject(valueNodeResource); IEnumerable <RDFTriple> unallowedTriples = valuenodeResourceGraph.Where(t => !allowedProperties.Any(p => p.Equals(t.Predicate))); foreach (RDFTriple unallowedTriple in unallowedTriples) { report.AddResult(new RDFValidationResult(shape, RDFVocabulary.SHACL.CLOSED_CONSTRAINT_COMPONENT, valueNodeResource, unallowedTriple.Predicate as RDFResource, unallowedTriple.Object, shape.Messages, shape.Severity)); } } } } #endregion return(report); }
/// <summary> /// Evaluates this constraint against the given data graph /// </summary> internal override RDFValidationReport ValidateConstraint(RDFShapesGraph shapesGraph, RDFGraph dataGraph, RDFShape shape, RDFPatternMember focusNode, List <RDFPatternMember> valueNodes) { RDFValidationReport report = new RDFValidationReport(); //Search for given property shape RDFPropertyShape propertyShape = shapesGraph.SelectShape(this.PropertyShapeUri.ToString()) as RDFPropertyShape; if (propertyShape == null) { return(report); } #region Evaluation RDFValidationReport propertyShapeReport = RDFValidationEngine.ValidateShape(shapesGraph, dataGraph, propertyShape, valueNodes); if (!propertyShapeReport.Conforms) { report.MergeResults(propertyShapeReport); } #endregion return(report); }