/// <summary> /// Gets a graph representation of this shapes graph /// </summary> public RDFGraph ToRDFGraph() { var result = new RDFGraph(); foreach (var shape in this) { result = result.UnionWith(shape.ToRDFGraph()); } result.SetContext(this.URI); return(result); }
/// <summary> /// Validates the given data graph against the given SHACL shapes graph /// </summary> public static RDFValidationReport Validate(this RDFShapesGraph shapesGraph, RDFGraph dataGraph) { RDFValidationReport report = new RDFValidationReport(new RDFResource()); if (dataGraph != null) { foreach (RDFShape shape in shapesGraph) { report.MergeResults(ValidateShape(shapesGraph, dataGraph, shape)); } } return(report); }
internal static RDFShapesGraph FromRDFGraph(RDFGraph graph) { if (graph != null) { RDFShapesGraph result = new RDFShapesGraph(new RDFResource(graph.Context.ToString())); DetectTypedNodeShapes(graph, result); DetectTypedPropertyShapes(graph, result); DetectInlinePropertyShapes(graph, result); return(result); } return(null); }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //sh:hasValue if (this.Value is RDFResource) result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.HAS_VALUE, (RDFResource)this.Value)); else result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.HAS_VALUE, (RDFLiteral)this.Value)); } return result; }
/// <summary> /// Given an attribute representing a RDF collection, iterates on its constituent elements /// to build its standard reification triples. /// </summary> internal static void ParseCollectionElements(Uri xmlBase, XmlNode predNode, RDFResource subj, RDFResource pred, RDFGraph result) { //Attach the collection as the blank object of the current pred RDFResource obj = new RDFResource(); result.AddTriple(new RDFTriple(subj, pred, obj)); //Iterate on the collection items to reify it if (predNode.HasChildNodes) { IEnumerator elems = predNode.ChildNodes.GetEnumerator(); while (elems != null && elems.MoveNext()) { XmlNode elem = (XmlNode)elems.Current; //Try to get items as "rdf:about" attributes, or as "rdf:resource" XmlAttribute elemUri = (GetRdfAboutAttribute(elem) ?? GetRdfResourceAttribute(elem)); if (elemUri != null) { //Sanitize eventual blank node or relative value, depending on attribute found elemUri.Value = ResolveRelativeNode(elemUri, xmlBase); // obj -> rdf:type -> rdf:list result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.LIST)); // obj -> rdf:first -> res result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.FIRST, new RDFResource(elemUri.Value))); //Last element of a collection must give a triple to a "rdf:nil" object RDFResource newObj; if (elem != predNode.ChildNodes.Item(predNode.ChildNodes.Count - 1)) { // obj -> rdf:rest -> newObj newObj = new RDFResource(); } else { // obj -> rdf:rest -> rdf:nil newObj = RDFVocabulary.RDF.NIL; } result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.REST, newObj)); obj = newObj; } } } }
/// <summary> /// Detects the typed instances of shacl:NodeShape and populates the shapes graph with their definition /// </summary> private static void DetectTypedNodeShapes(RDFGraph graph, RDFShapesGraph shapesGraph) { RDFGraph declaredNodeShapes = graph.SelectTriplesByPredicate(RDFVocabulary.RDF.TYPE) .SelectTriplesByObject(RDFVocabulary.SHACL.NODE_SHAPE); foreach (RDFTriple declaredNodeShape in declaredNodeShapes) { RDFNodeShape nodeShape = new RDFNodeShape((RDFResource)declaredNodeShape.Subject); DetectShapeTargets(graph, nodeShape); DetectShapeAttributes(graph, nodeShape); DetectShapeConstraints(graph, nodeShape); shapesGraph.AddShape(nodeShape); } }
/// <summary> /// Gives the subj node extracted from the attribute list of the current element /// </summary> internal static RDFResource GetSubjectNode(XmlNode subjNode, Uri xmlBase, RDFGraph result) { RDFResource subj = null; //If there are attributes, search them for the one representing the subj if (subjNode.Attributes != null && subjNode.Attributes.Count > 0) { //We are interested in finding the "rdf:about" node for the subj XmlAttribute rdfAbout = GetRdfAboutAttribute(subjNode); if (rdfAbout != null) { //Attribute found, but we must check if it is "rdf:ID", "rdf:nodeID" or a relative Uri: //in this case it must be resolved against the xmlBase namespace, or else it remains the same String rdfAboutValue = ResolveRelativeNode(rdfAbout, xmlBase); subj = new RDFResource(rdfAboutValue); } //If "rdf:about" attribute has been found for the subj, we must //check if the node is not a standard "rdf:Description": this is //the case we can directly build a triple with "rdf:type" pred if (subj != null && !CheckIfRdfDescriptionNode(subjNode)) { RDFResource obj = null; if (subjNode.NamespaceURI == String.Empty) { obj = new RDFResource(xmlBase + subjNode.LocalName); } else { obj = new RDFResource(subjNode.NamespaceURI + subjNode.LocalName); } result.AddTriple(new RDFTriple(subj, RDFVocabulary.RDF.TYPE, obj)); } } //There are no attributes, so there's only one way we can handle this element: //if it is a standard rdf:Description, it is a blank Subject else { if (CheckIfRdfDescriptionNode(subjNode)) { subj = new RDFResource(); } } return(subj); }
/// <summary> /// Builds the reification graph of the triple /// </summary> public RDFGraph ReifyTriple() { RDFGraph reifGraph = new RDFGraph(); reifGraph.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.STATEMENT)); reifGraph.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.SUBJECT, (RDFResource)this.Subject)); reifGraph.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.PREDICATE, (RDFResource)this.Predicate)); if (this.TripleFlavor == RDFModelEnums.RDFTripleFlavor.SPO) { reifGraph.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.OBJECT, (RDFResource)this.Object)); } else { reifGraph.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.OBJECT, (RDFLiteral)this.Object)); } return(reifGraph); }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //sh:maxExclusive if (this.Value is RDFResource) { result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.MAX_EXCLUSIVE, (RDFResource)this.Value)); } else { result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.MAX_EXCLUSIVE, (RDFLiteral)this.Value)); } } return(result); }
/// <summary> /// Builds the reification graph of the collection /// </summary> public RDFGraph ReifyCollection() { RDFGraph reifColl = new RDFGraph(); RDFResource reifSubj = this.ReificationSubject; int itemCount = 0; //Collection can be reified only if it has at least one item if (this.ItemsCount > 0) { foreach (object listEnum in this) { //Count the items to keep track of the last one, which will be connected to rdf:nil itemCount++; // Subject -> rdf:type -> rdf:List reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.LIST)); // Subject -> rdf:first -> RDFCollection.ITEM[i] if (this.ItemType == RDFModelEnums.RDFItemTypes.Resource) { reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.FIRST, (RDFResource)listEnum)); } else { reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.FIRST, (RDFLiteral)listEnum)); } //Not the last one: Subject -> rdf:rest -> NEWBLANK if (itemCount < this.ItemsCount) { RDFResource newSub = new RDFResource(); reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.REST, newSub)); reifSubj = newSub; } //The last one: Subject -> rdf:rest -> rdf:nil else { reifColl.AddTriple(new RDFTriple(reifSubj, RDFVocabulary.RDF.REST, RDFVocabulary.RDF.NIL)); } } } return(reifColl); }
/// <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> /// 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> /// Gets the direct (rdf:type) and indirect (rdfs:subClassOf) instances of the given class within the given data graph /// </summary> internal static List <RDFPatternMember> GetInstancesOfClass(this RDFGraph dataGraph, RDFResource className, HashSet <long> visitContext = null) { var result = new List <RDFPatternMember>(); if (className != null && dataGraph != null) { #region visitContext if (visitContext == null) { visitContext = new HashSet <long>() { { className.PatternMemberID } }; } else { if (!visitContext.Contains(className.PatternMemberID)) { visitContext.Add(className.PatternMemberID); } else { return(result); } } #endregion //rdf:type foreach (var triple in dataGraph.SelectTriplesByPredicate(RDFVocabulary.RDF.TYPE) .SelectTriplesByObject(className)) { result.Add(triple.Subject); } //rdfs:subClassOf foreach (var triple in dataGraph.SelectTriplesByPredicate(RDFVocabulary.RDFS.SUB_CLASS_OF) .SelectTriplesByObject(className)) { result.AddRange(dataGraph.GetInstancesOfClass((RDFResource)triple.Subject, visitContext)); } } return(result); }
/// <summary> /// Gets a graph representation of this shape /// </summary> public virtual RDFGraph ToRDFGraph() { var result = new RDFGraph(); //Severity switch (this.Severity) { case RDFValidationEnums.RDFShapeSeverity.Info: result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.SEVERITY_PROPERTY, RDFVocabulary.SHACL.INFO)); break; case RDFValidationEnums.RDFShapeSeverity.Warning: result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.SEVERITY_PROPERTY, RDFVocabulary.SHACL.WARNING)); break; case RDFValidationEnums.RDFShapeSeverity.Violation: result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.SEVERITY_PROPERTY, RDFVocabulary.SHACL.VIOLATION)); break; } //Deactivated if (this.Deactivated) { result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.DEACTIVATED, new RDFTypedLiteral("true", RDFModelEnums.RDFDatatypes.XSD_BOOLEAN))); } else { result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.DEACTIVATED, new RDFTypedLiteral("false", RDFModelEnums.RDFDatatypes.XSD_BOOLEAN))); } //Messages this.Messages.ForEach(message => result.AddTriple(new RDFTriple(this, RDFVocabulary.SHACL.MESSAGE, message))); //Targets this.Targets.ForEach(target => result = result.UnionWith(target.ToRDFGraph(this))); //Constraints this.Constraints.ForEach(constraint => result = result.UnionWith(constraint.ToRDFGraph(this))); result.SetContext(this.URI); return(result); }
/// <summary> /// Builds the reification graph of the container: /// Subject -> rdf:type -> [rdf:Bag|rdf:Seq|rdf:Alt] /// Subject -> rdf:_N -> RDFContainer.ITEM(N) /// </summary> public RDFGraph ReifyContainer() { RDFGraph reifCont = new RDFGraph(); // Subject -> rdf:type -> [rdf:Bag|rdf:Seq|rdf:Alt] switch (this.ContainerType) { case RDFModelEnums.RDFContainerTypes.Bag: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.BAG)); break; case RDFModelEnums.RDFContainerTypes.Seq: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.SEQ)); break; case RDFModelEnums.RDFContainerTypes.Alt: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.ALT)); break; default: throw new NotImplementedException(); break; } // Subject -> rdf:_N -> RDFContainer.ITEM(N) Int32 index = 0; foreach (Object item in this) { RDFResource ordPred = new RDFResource(RDFVocabulary.RDF.BASE_URI + "_" + (++index)); if (this.ItemType == RDFModelEnums.RDFItemTypes.Resource) { reifCont.AddTriple(new RDFTriple(this.ReificationSubject, ordPred, (RDFResource)item)); } else { reifCont.AddTriple(new RDFTriple(this.ReificationSubject, ordPred, (RDFLiteral)item)); } } return(reifCont); }
/// <summary> /// Gets the focus nodes of the given shape /// </summary> internal static List <RDFPatternMember> GetFocusNodesOf(this RDFGraph dataGraph, RDFShape shape) { List <RDFPatternMember> result = new List <RDFPatternMember>(); if (shape != null && dataGraph != null) { foreach (RDFTarget target in shape.Targets) { switch (target) { //sh:targetClass case RDFTargetClass targetClass: result.AddRange(dataGraph.GetInstancesOfClass(target.TargetValue) .OfType <RDFResource>()); break; //sh:targetNode case RDFTargetNode targetNode: result.Add(target.TargetValue); break; //sh:targetSubjectsOf case RDFTargetSubjectsOf targetSubjectsOf: result.AddRange(dataGraph.SelectTriplesByPredicate(target.TargetValue) .Select(x => x.Subject) .OfType <RDFResource>()); break; //sh:targetObjectsOf case RDFTargetObjectsOf targetObjectsOf: result.AddRange(dataGraph.SelectTriplesByPredicate(target.TargetValue) .Select(x => x.Object) .OfType <RDFResource>()); break; } } } return(RDFQueryUtilities.RemoveDuplicates(result)); }
/// <summary> /// Detects the attributes of the given shape /// </summary> private static void DetectShapeAttributes(RDFGraph graph, RDFShape shape) { RDFGraph shapeDefinition = graph.SelectTriplesBySubject(shape); //sh:severity (accepted occurrences: 1) RDFTriple shapeSeverity = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.SEVERITY_PROPERTY).FirstOrDefault(); if (shapeSeverity != null) { if (shapeSeverity.Object.Equals(RDFVocabulary.SHACL.INFO)) { shape.SetSeverity(RDFValidationEnums.RDFShapeSeverity.Info); } else if (shapeSeverity.Object.Equals(RDFVocabulary.SHACL.WARNING)) { shape.SetSeverity(RDFValidationEnums.RDFShapeSeverity.Warning); } } //sh:deactivated (accepted occurrences: 1) RDFTriple shapeDeactivated = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.DEACTIVATED).FirstOrDefault(); if (shapeDeactivated != null) { if (shapeDeactivated.Object is RDFTypedLiteral shapeDeactivatedLiteral && shapeDeactivatedLiteral.HasBooleanDatatype() && bool.Parse(shapeDeactivatedLiteral.Value)) { shape.Deactivate(); } } //sh:message (accepted occurrences: N) RDFGraph shapeMessages = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MESSAGE); foreach (RDFTriple shapeMessage in shapeMessages.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPL)) { shape.AddMessage((RDFLiteral)shapeMessage.Object); } }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //Get collection from language tags RDFCollection languageTags = new RDFCollection(RDFModelEnums.RDFItemTypes.Literal) { InternalReificationSubject = this }; foreach (string languageTag in this.LanguageTags) { languageTags.AddItem(new RDFPlainLiteral(languageTag)); } result.AddCollection(languageTags); //sh:languageIn result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.LANGUAGE_IN, languageTags.ReificationSubject)); } return(result); }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //Get collection from xoneShapes RDFCollection xoneShapes = new RDFCollection(RDFModelEnums.RDFItemTypes.Resource) { InternalReificationSubject = this }; foreach (RDFResource xoneShape in this.XoneShapes.Values) { xoneShapes.AddItem(xoneShape); } result.AddCollection(xoneShapes); //sh:xone result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.XONE, xoneShapes.ReificationSubject)); } return(result); }
/// <summary> /// Builds the reification graph of the container: /// Subject -> rdf:type -> [rdf:Bag|rdf:Seq|rdf:Alt] /// Subject -> rdf:_N -> RDFContainer.ITEM(N) /// </summary> public RDFGraph ReifyContainer() { RDFGraph reifCont = new RDFGraph(); // Subject -> rdf:type -> [rdf:Bag|rdf:Seq|rdf:Alt] switch (this.ContainerType) { case RDFModelEnums.RDFContainerTypes.Bag: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.BAG)); break; case RDFModelEnums.RDFContainerTypes.Seq: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.SEQ)); break; case RDFModelEnums.RDFContainerTypes.Alt: reifCont.AddTriple(new RDFTriple(this.ReificationSubject, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.ALT)); break; } // Subject -> rdf:_N -> RDFContainer.ITEM(N) int index = 0; foreach (object item in this) { RDFResource ordPred = new RDFResource(string.Concat(RDFVocabulary.RDF.BASE_URI, "_", (++index).ToString())); if (this.ItemType == RDFModelEnums.RDFItemTypes.Resource) { reifCont.AddTriple(new RDFTriple(this.ReificationSubject, ordPred, (RDFResource)item)); } else { reifCont.AddTriple(new RDFTriple(this.ReificationSubject, ordPred, (RDFLiteral)item)); } } return(reifCont); }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //sh:qualifiedValueShape result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.QUALIFIED_VALUE_SHAPE, this.QualifiedValueShapeUri)); //sh:qualifiedMinCount if (this.QualifiedValueMinCount.HasValue) { result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.QUALIFIED_MIN_COUNT, new RDFTypedLiteral(this.QualifiedValueMinCount.ToString(), RDFModelEnums.RDFDatatypes.XSD_INTEGER))); } //sh:qualifiedMaxCount if (this.QualifiedValueMaxCount.HasValue) { result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.QUALIFIED_MAX_COUNT, new RDFTypedLiteral(this.QualifiedValueMaxCount.ToString(), RDFModelEnums.RDFDatatypes.XSD_INTEGER))); } } return(result); }
/// <summary> /// Detects the targets of the given shape /// </summary> private static void DetectShapeTargets(RDFGraph graph, RDFShape shape) { RDFGraph shapeDefinition = graph.SelectTriplesBySubject(shape); //sh:TargetClass (accepted occurrences: N) RDFGraph targetClasses = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.TARGET_CLASS); foreach (RDFTriple targetClass in targetClasses.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddTarget(new RDFTargetClass((RDFResource)targetClass.Object)); } //sh:TargetNode (accepted occurrences: N) RDFGraph targetNodes = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.TARGET_NODE); foreach (RDFTriple targetNode in targetNodes.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddTarget(new RDFTargetNode((RDFResource)targetNode.Object)); } //sh:TargetSubjectsOf (accepted occurrences: N) RDFGraph targetSubjectsOf = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.TARGET_SUBJECTS_OF); foreach (RDFTriple targetSubjectOf in targetSubjectsOf.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddTarget(new RDFTargetSubjectsOf((RDFResource)targetSubjectOf.Object)); } //sh:TargetObjectsOf (accepted occurrences: N) RDFGraph targetObjectsOf = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.TARGET_OBJECTS_OF); foreach (RDFTriple targetObjectOf in targetObjectsOf.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddTarget(new RDFTargetObjectsOf((RDFResource)targetObjectOf.Object)); } }
/// <summary> /// Gets a graph representation of this constraint /// </summary> internal override RDFGraph ToRDFGraph(RDFShape shape) { RDFGraph result = new RDFGraph(); if (shape != null) { //sh:nodeKind switch (this.NodeKind) { case RDFValidationEnums.RDFNodeKinds.BlankNode: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.BLANK_NODE)); break; case RDFValidationEnums.RDFNodeKinds.BlankNodeOrIRI: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.BLANK_NODE_OR_IRI)); break; case RDFValidationEnums.RDFNodeKinds.BlankNodeOrLiteral: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.BLANK_NODE_OR_LITERAL)); break; case RDFValidationEnums.RDFNodeKinds.IRI: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.IRI)); break; case RDFValidationEnums.RDFNodeKinds.IRIOrLiteral: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.IRI_OR_LITERAL)); break; case RDFValidationEnums.RDFNodeKinds.Literal: result.AddTriple(new RDFTriple(shape, RDFVocabulary.SHACL.NODE_KIND, RDFVocabulary.SHACL.LITERAL)); break; } } return(result); }
/// <summary> /// Validates the given data graph against the given SHACL shape /// </summary> internal static RDFValidationReport ValidateShape(RDFShapesGraph shapesGraph, RDFGraph dataGraph, RDFShape shape, List <RDFPatternMember> focusNodes = null) { RDFValidationReport report = new RDFValidationReport(new RDFResource()); if (!shape.Deactivated) { //Resolve focus nodes if (focusNodes == null) { focusNodes = dataGraph.GetFocusNodesOf(shape); } foreach (RDFPatternMember focusNode in focusNodes) { //Resolve value nodes List <RDFPatternMember> valueNodes = dataGraph.GetValueNodesOf(shape, focusNode); //Evaluate constraints foreach (RDFConstraint constraint in shape) { report.MergeResults(constraint.ValidateConstraint(shapesGraph, dataGraph, shape, focusNode, valueNodes)); } } } return(report); }
/// <summary> /// Asynchronously validates the given data graph against the given SHACL shapes graph /// </summary> public static Task <RDFValidationReport> ValidateAsync(this RDFShapesGraph shapesGraph, RDFGraph dataGraph) => Task.Run(() => Validate(shapesGraph, dataGraph));
/// <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 (!valueNodes.Any(v => v.Equals(this.Value))) { report.AddResult(new RDFValidationResult(shape, RDFVocabulary.SHACL.HAS_VALUE_CONSTRAINT_COMPONENT, focusNode, shape is RDFPropertyShape ? ((RDFPropertyShape)shape).Path : null, null, 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); }
/// <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 foreach (RDFPatternMember valueNode in valueNodes) { Int32 comparison = RDFQueryUtilities.CompareRDFPatternMembers(this.Value, valueNode); if (comparison == -99 || comparison <= 0) { report.AddResult(new RDFValidationResult(shape, RDFVocabulary.SHACL.MAX_EXCLUSIVE_CONSTRAINT_COMPONENT, focusNode, shape is RDFPropertyShape ? ((RDFPropertyShape)shape).Path : null, valueNode, 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(new RDFResource()); #region Evaluation foreach (RDFPatternMember valueNode in valueNodes) { switch (valueNode) { //PlainLiteral case RDFPlainLiteral valueNodePlainLiteral: bool langMatches = false; var langTagsEnumerator = this.LanguageTags.GetEnumerator(); while (langTagsEnumerator.MoveNext() && !langMatches) { //NO language is found in the variable if (langTagsEnumerator.Current == string.Empty) { langMatches = !Regex.IsMatch(valueNodePlainLiteral.ToString(), "@[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$", RegexOptions.Compiled | RegexOptions.IgnoreCase); } //ANY language is found in the variable else if (langTagsEnumerator.Current == "*") { langMatches = Regex.IsMatch(valueNodePlainLiteral.ToString(), "@[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$", RegexOptions.Compiled | RegexOptions.IgnoreCase); } //GIVEN language is found in the variable else { langMatches = Regex.IsMatch(valueNodePlainLiteral.ToString(), string.Concat("@", langTagsEnumerator.Current, "(-[a-zA-Z0-9]{1,8})*$"), RegexOptions.IgnoreCase); } } if (!langMatches) { report.AddResult(new RDFValidationResult(shape, RDFVocabulary.SHACL.LANGUAGE_IN_CONSTRAINT_COMPONENT, focusNode, shape is RDFPropertyShape ? ((RDFPropertyShape)shape).Path : null, valueNode, shape.Messages, shape.Severity)); } break; //Resource/TypedLiteral default: report.AddResult(new RDFValidationResult(shape, RDFVocabulary.SHACL.LANGUAGE_IN_CONSTRAINT_COMPONENT, focusNode, shape is RDFPropertyShape ? ((RDFPropertyShape)shape).Path : null, valueNode, shape.Messages, shape.Severity)); break; } } #endregion return(report); }
/// <summary> /// Detects the constraints of the given shape /// </summary> private static void DetectShapeConstraints(RDFGraph graph, RDFShape shape) { RDFGraph shapeDefinition = graph.SelectTriplesBySubject(shape); //sh:and (accepted occurrences: N) RDFGraph shapeAndConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.AND); foreach (RDFTriple shapeAndConstraint in shapeAndConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { RDFAndConstraint andConstraint = new RDFAndConstraint(); RDFCollection andConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)shapeAndConstraint.Object, RDFModelEnums.RDFTripleFlavors.SPO); andConstraintCollection.Items.ForEach(item => andConstraint.AddShape((RDFResource)item)); shape.AddConstraint(andConstraint); } //sh:class (accepted occurrences: N) RDFGraph shapeClassConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.CLASS); foreach (RDFTriple shapeClassConstraint in shapeClassConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFClassConstraint((RDFResource)shapeClassConstraint.Object)); } //sh:closed (accepted occurrences: 1) RDFTriple shapeClosedConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.CLOSED).FirstOrDefault(); if (shapeClosedConstraint != null) { if (shapeClosedConstraint.Object is RDFTypedLiteral shapeClosedConstraintLiteral && shapeClosedConstraintLiteral.HasBooleanDatatype()) { RDFClosedConstraint closedConstraint = new RDFClosedConstraint(bool.Parse(shapeClosedConstraintLiteral.Value)); //sh:ignoredProperties (accepted occurrences: 1) RDFTriple shapeIgnoredPropertiesConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.IGNORED_PROPERTIES).FirstOrDefault(); if (shapeIgnoredPropertiesConstraint != null) { if (shapeIgnoredPropertiesConstraint.Object is RDFResource shapeIgnoredPropertiesConstraintResource) { RDFCollection shapeIgnoredPropertiesConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, shapeIgnoredPropertiesConstraintResource, RDFModelEnums.RDFTripleFlavors.SPO); shapeIgnoredPropertiesConstraintCollection.Items.ForEach(item => closedConstraint.AddIgnoredProperty((RDFResource)item)); } } shape.AddConstraint(closedConstraint); } } //sh:datatype (accepted occurrences: N) RDFGraph shapeDatatypeConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.DATATYPE); foreach (RDFTriple shapeDatatypeConstraint in shapeDatatypeConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFDatatypeConstraint(RDFModelUtilities.GetDatatypeFromString(shapeDatatypeConstraint.Object.ToString()))); } //sh:disjoint (accepted occurrences: N) RDFGraph shapeDisjointConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.DISJOINT); foreach (RDFTriple shapeDisjointConstraint in shapeDisjointConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFDisjointConstraint((RDFResource)shapeDisjointConstraint.Object)); } //sh:equals (accepted occurrences: N) RDFGraph shapeEqualsConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.EQUALS); foreach (RDFTriple shapeEqualsConstraint in shapeEqualsConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFEqualsConstraint((RDFResource)shapeEqualsConstraint.Object)); } //sh:hasValue (accepted occurrences: N) RDFGraph shapeHasValueConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.HAS_VALUE); foreach (RDFTriple shapeHasValueConstraint in shapeHasValueConstraints) { if (shapeHasValueConstraint.Object is RDFResource) { shape.AddConstraint(new RDFHasValueConstraint((RDFResource)shapeHasValueConstraint.Object)); } else if (shapeHasValueConstraint.Object is RDFLiteral) { shape.AddConstraint(new RDFHasValueConstraint((RDFLiteral)shapeHasValueConstraint.Object)); } } //sh:in (accepted occurrences: N) RDFGraph shapeInConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.IN); foreach (RDFTriple shapeInConstraint in shapeInConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { RDFModelEnums.RDFTripleFlavors shapeInConstraintCollectionFlavor = RDFModelUtilities.DetectCollectionFlavorFromGraph(graph, (RDFResource)shapeInConstraint.Object); RDFCollection shapeInConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)shapeInConstraint.Object, shapeInConstraintCollectionFlavor); RDFInConstraint inConstraint = new RDFInConstraint(shapeInConstraintCollection.ItemType); shapeInConstraintCollection.Items.ForEach(item => { if (item is RDFResource) { inConstraint.AddValue((RDFResource)item); } else if (item is RDFLiteral) { inConstraint.AddValue((RDFLiteral)item); } }); shape.AddConstraint(inConstraint); } //sh:languageIn (accepted occurrences: N) RDFGraph shapeLanguageInConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.LANGUAGE_IN); foreach (RDFTriple shapeLanguageInConstraint in shapeLanguageInConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { RDFCollection shapeLanguageInConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)shapeLanguageInConstraint.Object, RDFModelEnums.RDFTripleFlavors.SPL); shape.AddConstraint(new RDFLanguageInConstraint(shapeLanguageInConstraintCollection.Select(x => x.ToString()).ToList())); } //sh:lessThan (accepted occurrences: N) RDFGraph shapeLessThanConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.LESS_THAN); foreach (RDFTriple shapeLessThanConstraint in shapeLessThanConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFLessThanConstraint((RDFResource)shapeLessThanConstraint.Object)); } //sh:lessThanOrEquals (accepted occurrences: N) RDFGraph shapeLessThanOrEqualsConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.LESS_THAN_OR_EQUALS); foreach (RDFTriple shapeLessThanOrEqualsConstraint in shapeLessThanOrEqualsConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFLessThanOrEqualsConstraint((RDFResource)shapeLessThanOrEqualsConstraint.Object)); } //sh:maxCount (accepted occurrences: 1) RDFTriple shapeMaxCountConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MAX_COUNT).FirstOrDefault(); if (shapeMaxCountConstraint != null) { if (shapeMaxCountConstraint.Object is RDFTypedLiteral shaclMaxCountConstraintLiteral && shaclMaxCountConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMaxCountConstraint(int.Parse(shaclMaxCountConstraintLiteral.Value))); } } //sh:maxExclusive (accepted occurrences: 1) RDFTriple shapeMaxExclusiveConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MAX_EXCLUSIVE).FirstOrDefault(); if (shapeMaxExclusiveConstraint != null) { if (shapeMaxExclusiveConstraint.Object is RDFResource) { shape.AddConstraint(new RDFMaxExclusiveConstraint((RDFResource)shapeMaxExclusiveConstraint.Object)); } else if (shapeMaxExclusiveConstraint.Object is RDFLiteral) { shape.AddConstraint(new RDFMaxExclusiveConstraint((RDFLiteral)shapeMaxExclusiveConstraint.Object)); } } //sh:maxInclusive (accepted occurrences: 1) RDFTriple shapeMaxInclusiveConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MAX_INCLUSIVE).FirstOrDefault(); if (shapeMaxInclusiveConstraint != null) { if (shapeMaxInclusiveConstraint.Object is RDFResource) { shape.AddConstraint(new RDFMaxInclusiveConstraint((RDFResource)shapeMaxInclusiveConstraint.Object)); } else if (shapeMaxInclusiveConstraint.Object is RDFLiteral) { shape.AddConstraint(new RDFMaxInclusiveConstraint((RDFLiteral)shapeMaxInclusiveConstraint.Object)); } } //sh:maxLength (accepted occurrences: 1) RDFTriple shapeMaxLengthConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MAX_LENGTH).FirstOrDefault(); if (shapeMaxLengthConstraint != null) { if (shapeMaxLengthConstraint.Object is RDFTypedLiteral shaclMaxLengthConstraintLiteral && shaclMaxLengthConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMaxLengthConstraint(int.Parse(shaclMaxLengthConstraintLiteral.Value))); } } //sh:minCount (accepted occurrences: 1) RDFTriple shapeMinCountConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MIN_COUNT).FirstOrDefault(); if (shapeMinCountConstraint != null) { if (shapeMinCountConstraint.Object is RDFTypedLiteral shaclMinCountConstraintLiteral && shaclMinCountConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMinCountConstraint(int.Parse(shaclMinCountConstraintLiteral.Value))); } } //sh:minExclusive (accepted occurrences: 1) RDFTriple shapeMinExclusiveConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MIN_EXCLUSIVE).FirstOrDefault(); if (shapeMinExclusiveConstraint != null) { if (shapeMinExclusiveConstraint.Object is RDFResource) { shape.AddConstraint(new RDFMinExclusiveConstraint((RDFResource)shapeMinExclusiveConstraint.Object)); } else if (shapeMinExclusiveConstraint.Object is RDFLiteral) { shape.AddConstraint(new RDFMinExclusiveConstraint((RDFLiteral)shapeMinExclusiveConstraint.Object)); } } //sh:minInclusive (accepted occurrences: 1) RDFTriple shapeMinInclusiveConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MIN_INCLUSIVE).FirstOrDefault(); if (shapeMinInclusiveConstraint != null) { if (shapeMinInclusiveConstraint.Object is RDFResource) { shape.AddConstraint(new RDFMinInclusiveConstraint((RDFResource)shapeMinInclusiveConstraint.Object)); } else if (shapeMinInclusiveConstraint.Object is RDFLiteral) { shape.AddConstraint(new RDFMinInclusiveConstraint((RDFLiteral)shapeMinInclusiveConstraint.Object)); } } //sh:minLength (accepted occurrences: 1) RDFTriple shapeMinLengthConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.MIN_LENGTH).FirstOrDefault(); if (shapeMinLengthConstraint != null) { if (shapeMinLengthConstraint.Object is RDFTypedLiteral shaclMinLengthConstraintLiteral && shaclMinLengthConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMinLengthConstraint(int.Parse(shaclMinLengthConstraintLiteral.Value))); } } //sh:node (accepted occurrences: N) RDFGraph shapeNodeConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.NODE); foreach (RDFTriple shapeNodeConstraint in shapeNodeConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFNodeConstraint((RDFResource)shapeNodeConstraint.Object)); } //sh:nodeKind (accepted occurrences: 1) RDFTriple shapeNodeKindConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.NODE_KIND).FirstOrDefault(); if (shapeNodeKindConstraint != null) { if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.BLANK_NODE)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNode)); } else if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.BLANK_NODE_OR_IRI)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNodeOrIRI)); } else if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.BLANK_NODE_OR_LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNodeOrLiteral)); } else if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.IRI)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.IRI)); } else if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.IRI_OR_LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.IRIOrLiteral)); } else if (shapeNodeKindConstraint.Object.Equals(RDFVocabulary.SHACL.LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.Literal)); } } //sh:not (accepted occurrences: N) RDFGraph shapeNotConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.NOT); foreach (RDFTriple shapeNotConstraint in shapeNotConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFNotConstraint((RDFResource)shapeNotConstraint.Object)); } //sh:or (accepted occurrences: N) RDFGraph shapeOrConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.OR); foreach (RDFTriple shapeOrConstraint in shapeOrConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { RDFOrConstraint orConstraint = new RDFOrConstraint(); RDFCollection orConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)shapeOrConstraint.Object, RDFModelEnums.RDFTripleFlavors.SPO); orConstraintCollection.Items.ForEach(item => orConstraint.AddShape((RDFResource)item)); shape.AddConstraint(orConstraint); } //sh:pattern (accepted occurrences: 1) RDFTriple shapePatternConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.PATTERN).FirstOrDefault(); if (shapePatternConstraint != null) { if (shapePatternConstraint.Object is RDFTypedLiteral shapePatternConstraintLiteral && shapePatternConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_STRING)) { //sh:flags (accepted occurrences: 1) RegexOptions regexOptions = RegexOptions.None; RDFTriple shapeFlagsConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.FLAGS).FirstOrDefault(); if (shapeFlagsConstraint != null) { if (shapeFlagsConstraint.Object is RDFTypedLiteral shapeFlagsConstraintLiteral && shapeFlagsConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_STRING)) { if (shapeFlagsConstraintLiteral.Value.Contains("i")) { regexOptions |= RegexOptions.IgnoreCase; } if (shapeFlagsConstraintLiteral.Value.Contains("s")) { regexOptions |= RegexOptions.Singleline; } if (shapeFlagsConstraintLiteral.Value.Contains("m")) { regexOptions |= RegexOptions.Multiline; } if (shapeFlagsConstraintLiteral.Value.Contains("x")) { regexOptions |= RegexOptions.IgnorePatternWhitespace; } } } shape.AddConstraint(new RDFPatternConstraint(new Regex(shapePatternConstraintLiteral.Value, regexOptions))); } } //sh:property (accepted occurrences: N) RDFGraph shapePropertyConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.PROPERTY); foreach (RDFTriple shapePropertyConstraint in shapePropertyConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { shape.AddConstraint(new RDFPropertyConstraint((RDFResource)shapePropertyConstraint.Object)); } //sh:qualifiedValueShape (accepted occurrences: 1) RDFTriple shapeQualifiedValueConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.QUALIFIED_VALUE_SHAPE).FirstOrDefault(); if (shapeQualifiedValueConstraint != null) { if (shapeQualifiedValueConstraint.Object is RDFResource) { //sh:qualifiedMinCount (accepted occurrences: 1) int? qualifiedMinCountValue = null; RDFTriple shapeQualifiedMinCountConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.QUALIFIED_MIN_COUNT).FirstOrDefault(); if (shapeQualifiedMinCountConstraint != null) { if (shapeQualifiedMinCountConstraint.Object is RDFTypedLiteral shapeQualifiedMinCountConstraintLiteral && shapeQualifiedMinCountConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { qualifiedMinCountValue = int.Parse(shapeQualifiedMinCountConstraintLiteral.Value); } } //sh:qualifiedMaxCount (accepted occurrences: 1) int? qualifiedMaxCountValue = null; RDFTriple shapeQualifiedMaxCountConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.QUALIFIED_MAX_COUNT).FirstOrDefault(); if (shapeQualifiedMaxCountConstraint != null) { if (shapeQualifiedMaxCountConstraint.Object is RDFTypedLiteral shapeQualifiedMaxCountConstraintLiteral && shapeQualifiedMaxCountConstraintLiteral.Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { qualifiedMaxCountValue = int.Parse(shapeQualifiedMaxCountConstraintLiteral.Value); } } shape.AddConstraint(new RDFQualifiedValueShapeConstraint((RDFResource)shapeQualifiedValueConstraint.Object, qualifiedMinCountValue, qualifiedMaxCountValue)); } } //sh:uniqueLang (accepted occurrences: 1) RDFTriple shapeUniqueLangConstraint = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.UNIQUE_LANG).FirstOrDefault(); if (shapeUniqueLangConstraint != null) { if (shapeUniqueLangConstraint.Object is RDFTypedLiteral shapeUniqueLangConstraintLiteral && shapeUniqueLangConstraintLiteral.HasBooleanDatatype()) { shape.AddConstraint(new RDFUniqueLangConstraint(bool.Parse(shapeUniqueLangConstraintLiteral.Value))); } } //sh:xone (accepted occurrences: N) RDFGraph shapeXoneConstraints = shapeDefinition.SelectTriplesByPredicate(RDFVocabulary.SHACL.XONE); foreach (RDFTriple shapeXoneConstraint in shapeXoneConstraints.Where(t => t.TripleFlavor == RDFModelEnums.RDFTripleFlavors.SPO)) { RDFXoneConstraint xoneConstraint = new RDFXoneConstraint(); RDFCollection xoneConstraintCollection = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)shapeXoneConstraint.Object, RDFModelEnums.RDFTripleFlavors.SPO); xoneConstraintCollection.Items.ForEach(item => xoneConstraint.AddShape((RDFResource)item)); shape.AddConstraint(xoneConstraint); } }