/// <summary> /// Parses the current quadruple of the data reader /// </summary> internal static RDFQuadruple ParseQuadruple(IDataReader fetchedQuadruples) { if (fetchedQuadruples != null) { RDFContext qContext = new RDFContext(fetchedQuadruples["Context"].ToString()); RDFResource qSubject = new RDFResource(fetchedQuadruples["Subject"].ToString()); RDFResource qPredicate = new RDFResource(fetchedQuadruples["Predicate"].ToString()); //SPO-flavour quadruple if (fetchedQuadruples["TripleFlavor"].ToString().Equals("1")) { RDFResource qObject = new RDFResource(fetchedQuadruples["Object"].ToString()); return(new RDFQuadruple(qContext, qSubject, qPredicate, qObject)); } //SPL-flavour quadruple string literal = fetchedQuadruples["Object"].ToString(); //PlainLiteral int lastIndexOfDatatype = literal.LastIndexOf("^^", StringComparison.OrdinalIgnoreCase); int lastIndexOfLanguage = literal.LastIndexOf("@", StringComparison.OrdinalIgnoreCase); if (!literal.Contains("^^") || literal.EndsWith("^^") || RDFModelUtilities.GetUriFromString(literal.Substring(lastIndexOfDatatype + 2)) == null) { RDFPlainLiteral pLit = null; if (RDFNTriples.regexLPL.Match(literal).Success) { string pLitValue = literal.Substring(0, lastIndexOfLanguage); string pLitLang = literal.Substring(lastIndexOfLanguage + 1); pLit = new RDFPlainLiteral(pLitValue, pLitLang); } else { pLit = new RDFPlainLiteral(literal); } return(new RDFQuadruple(qContext, qSubject, qPredicate, pLit)); } //TypedLiteral string tLitValue = literal.Substring(0, lastIndexOfDatatype); string tLitDatatype = literal.Substring(lastIndexOfDatatype + 2); RDFModelEnums.RDFDatatypes dt = RDFModelUtilities.GetDatatypeFromString(tLitDatatype); RDFTypedLiteral tLit = new RDFTypedLiteral(tLitValue, dt); return(new RDFQuadruple(qContext, qSubject, qPredicate, tLit)); } throw new RDFStoreException("Cannot parse quadruple because given \"fetchedQuadruples\" parameter is null."); }
/// <summary> /// Parses the given string to return an instance of pattern member /// </summary> internal static RDFPatternMember ParseRDFPatternMember(string pMember) { if (pMember == null) { throw new RDFQueryException("Cannot parse pattern member because given \"pMember\" parameter is null."); } #region Uri if (Uri.TryCreate(pMember, UriKind.Absolute, out _)) { return(new RDFResource(pMember)); } #endregion #region Plain Literal int lastIndexOfDatatype = pMember.LastIndexOf("^^", StringComparison.OrdinalIgnoreCase); int lastIndexOfLanguage = pMember.LastIndexOf("@", StringComparison.OrdinalIgnoreCase); if (!pMember.Contains("^^") || pMember.EndsWith("^^") || RDFModelUtilities.GetUriFromString(pMember.Substring(lastIndexOfDatatype + 2)) == null) { RDFPlainLiteral pLit = null; if (RDFNTriples.regexLPL.Match(pMember).Success) { string pLitVal = pMember.Substring(0, lastIndexOfLanguage); string pLitLng = pMember.Substring(lastIndexOfLanguage + 1); pLit = new RDFPlainLiteral(pLitVal, pLitLng); } else { pLit = new RDFPlainLiteral(pMember); } return(pLit); } #endregion #region Typed Literal string tLitValue = pMember.Substring(0, lastIndexOfDatatype); string tLitDatatype = pMember.Substring(lastIndexOfDatatype + 2); RDFModelEnums.RDFDatatypes dt = RDFModelUtilities.GetDatatypeFromString(tLitDatatype); RDFTypedLiteral tLit = new RDFTypedLiteral(tLitValue, dt); return(tLit); #endregion }
/// <summary> /// Deserializes the given N-Quads stream to a memory store. /// </summary> internal static RDFMemoryStore Deserialize(Stream inputStream) { Int64 nquadIndex = 0; try { #region deserialize using (StreamReader sr = new StreamReader(inputStream)) { RDFMemoryStore result = new RDFMemoryStore(); String nquad = String.Empty; String[] tokens = new String[4]; RDFResource S = null; RDFResource P = null; RDFResource O = null; RDFLiteral L = null; RDFContext C = new RDFContext(); while ((nquad = sr.ReadLine()) != null) { nquadIndex++; #region sanitize & tokenize //Cleanup previous data S = null; tokens[0] = String.Empty; P = null; tokens[1] = String.Empty; O = null; L = null; tokens[2] = String.Empty; C = new RDFContext(); tokens[3] = String.Empty; //Preliminary sanitizations: clean trailing space-like chars nquad = nquad.Trim(new Char[] { ' ', '\t', '\r', '\n' }); //Skip empty or comment lines if (nquad == String.Empty || nquad.StartsWith("#")) { continue; } //Tokenizes the sanitized quad tokens = TokenizeNQuad(nquad); #endregion #region subj String subj = tokens[0].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }) .Replace("_:", "bnode:"); S = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(subj)); #endregion #region pred String pred = tokens[1].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }); P = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(pred)); #endregion #region object if (tokens[2].StartsWith("<") || tokens[2].StartsWith("bnode:") || tokens[2].StartsWith("_:")) { String obj = tokens[2].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }) .Replace("_:", "bnode:") .Trim(new Char[] { ' ', '\n', '\t', '\r' }); O = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(obj)); } #endregion #region literal else { #region sanitize tokens[2] = RDFNTriples.regexSqt.Replace(tokens[2], String.Empty); tokens[2] = RDFNTriples.regexEqt.Replace(tokens[2], String.Empty); tokens[2] = tokens[2].Replace("\\\"", "\"") .Replace("\\n", "\n") .Replace("\\t", "\t") .Replace("\\r", "\r"); tokens[2] = RDFModelUtilities.ASCII_To_Unicode(tokens[2]); #endregion #region plain literal if (!tokens[2].Contains("^^") || tokens[2].EndsWith("^^") || tokens[2].Substring(tokens[2].LastIndexOf("^^", StringComparison.Ordinal) + 2, 1) != "<") { if (RDFNTriples.regexLPL.Match(tokens[2]).Success) { tokens[2] = tokens[2].Replace("\"@", "@"); String pLitValue = tokens[2].Substring(0, tokens[2].LastIndexOf("@", StringComparison.Ordinal)); String pLitLang = tokens[2].Substring(tokens[2].LastIndexOf("@", StringComparison.Ordinal) + 1); L = new RDFPlainLiteral(HttpUtility.HtmlDecode(pLitValue), pLitLang); } else { L = new RDFPlainLiteral(HttpUtility.HtmlDecode(tokens[2])); } } #endregion #region typed literal else { tokens[2] = tokens[2].Replace("\"^^", "^^"); String tLitValue = tokens[2].Substring(0, tokens[2].LastIndexOf("^^", StringComparison.Ordinal)); String tLitDatatype = tokens[2].Substring(tokens[2].LastIndexOf("^^", StringComparison.Ordinal) + 2) .TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }); RDFModelEnums.RDFDatatype dt = RDFModelUtilities.GetDatatypeFromString(tLitDatatype); L = new RDFTypedLiteral(HttpUtility.HtmlDecode(tLitValue), dt); } #endregion } #endregion #region context if (!String.IsNullOrEmpty(tokens[3])) { String ctx = tokens[3].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }); Uri ctxUri = null; if (Uri.TryCreate(ctx, UriKind.Absolute, out ctxUri)) { C = new RDFContext(RDFModelUtilities.ASCII_To_Unicode(ctxUri.ToString())); } else { throw new RDFModelException("found context '" + ctx + "' which is not a well-formed absolute Uri"); } } #endregion #region addquadruple if (O != null) { result.AddQuadruple(new RDFQuadruple(C, S, P, O)); } else { result.AddQuadruple(new RDFQuadruple(C, S, P, L)); } #endregion } return(result); } #endregion } catch (Exception ex) { throw new RDFModelException("Cannot deserialize N-Quads (line " + nquadIndex + ") because: " + ex.Message, ex); } }
/// <summary> /// Deserializes the given TriX stream to a memory store. /// </summary> internal static RDFMemoryStore Deserialize(Stream inputStream) { try { #region deserialize RDFMemoryStore result = new RDFMemoryStore(); Dictionary <Int64, RDFGraph> graphs = new Dictionary <Int64, RDFGraph>(); using (StreamReader streamReader = new StreamReader(inputStream, Encoding.UTF8)) { using (XmlTextReader trixReader = new XmlTextReader(streamReader)) { trixReader.DtdProcessing = DtdProcessing.Parse; trixReader.Normalization = false; #region document XmlDocument trixDoc = new XmlDocument(); trixDoc.Load(trixReader); #endregion #region graph if (trixDoc.DocumentElement != null) { #region graphs extraction var graphEnum = trixDoc.DocumentElement.ChildNodes.GetEnumerator(); while (graphEnum != null && graphEnum.MoveNext()) { XmlNode graph = (XmlNode)graphEnum.Current; if (!graph.Name.Equals("graph", StringComparison.Ordinal)) { throw new RDFModelException(" a \"<graph>\" element was expected, instead of unrecognized \"<" + graph.Name + ">\"."); } Uri graphUri = RDFNamespaceRegister.DefaultNamespace.NamespaceUri; Int64 graphID = RDFNamespaceRegister.DefaultNamespace.NamespaceID; if (!graphs.ContainsKey(graphID)) { graphs.Add(graphID, new RDFGraph().SetContext(graphUri)); } #region triple var encodedUris = 0; var tripleEnum = graph.ChildNodes.GetEnumerator(); while (tripleEnum != null && tripleEnum.MoveNext()) { XmlNode triple = (XmlNode)tripleEnum.Current; #region uri if (triple.Name.Equals("uri", StringComparison.Ordinal)) { encodedUris++; if (encodedUris > 1) { throw new RDFModelException(" given file encodes a graph with more than one \"<uri>\" element."); } graphUri = RDFModelUtilities.GetUriFromString(triple.ChildNodes[0].InnerText); graphID = RDFModelUtilities.CreateHash(graphUri.ToString()); if (!graphs.ContainsKey(graphID)) { graphs.Add(graphID, new RDFGraph().SetContext(graphUri)); } } #endregion #region triple else if (triple.Name.Equals("triple", StringComparison.Ordinal) && triple.ChildNodes.Count == 3) { #region subj //Subject is a resource ("<uri>") or a blank node ("<id>") if (triple.ChildNodes[0].Name.Equals("uri", StringComparison.Ordinal) || triple.ChildNodes[0].Name.Equals("id", StringComparison.Ordinal)) { //Sanitize eventual blank node value if (triple.ChildNodes[0].Name.Equals("id", StringComparison.Ordinal)) { if (!triple.ChildNodes[0].InnerText.StartsWith("bnode:")) { triple.ChildNodes[0].InnerText = "bnode:" + triple.ChildNodes[0].InnerText.Replace("_:", String.Empty); } } } //Subject is not valid: exception must be raised else { throw new RDFModelException("subject (" + triple.ChildNodes[0].Name + ") of \"<triple>\" element is neither \"<uri>\" or \"<id>\"."); } #endregion #region pred //Predicate is not valid: exception must be raised if (!triple.ChildNodes[1].Name.Equals("uri", StringComparison.Ordinal)) { throw new RDFModelException("predicate (" + triple.ChildNodes[1].Name + ") of \"<triple>\" element must be \"<uri>\"."); } #endregion #region object //Object is a resource ("<uri>") or a blank node ("<id>") if (triple.ChildNodes[2].Name.Equals("uri", StringComparison.Ordinal) || triple.ChildNodes[2].Name.Equals("id", StringComparison.Ordinal)) { //Sanitize eventual blank node value if (triple.ChildNodes[2].Name.Equals("id", StringComparison.Ordinal)) { if (!triple.ChildNodes[2].InnerText.StartsWith("bnode:")) { triple.ChildNodes[2].InnerText = "bnode:" + triple.ChildNodes[2].InnerText.Replace("_:", String.Empty); } } graphs[graphID].AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFResource(triple.ChildNodes[2].InnerText))); } #endregion #region literal #region plain literal else if (triple.ChildNodes[2].Name.Equals("plainLiteral")) { if (triple.ChildNodes[2].Attributes != null && triple.ChildNodes[2].Attributes.Count > 0) { XmlAttribute xmlLang = triple.ChildNodes[2].Attributes[RDFVocabulary.XML.PREFIX + ":lang"]; if (xmlLang != null) { //Plain literal with language graphs[graphID].AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(RDFModelUtilities.ASCII_To_Unicode(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText)), xmlLang.Value))); } else { //Plain literal without language graphs[graphID].AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(RDFModelUtilities.ASCII_To_Unicode(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText))))); } } else { //Plain literal without language graphs[graphID].AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(RDFModelUtilities.ASCII_To_Unicode(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText))))); } } #endregion #region typed literal else if (triple.ChildNodes[2].Name.Equals("typedLiteral", StringComparison.Ordinal)) { if (triple.ChildNodes[2].Attributes != null && triple.ChildNodes[2].Attributes.Count > 0) { XmlAttribute rdfDtype = triple.ChildNodes[2].Attributes["datatype"]; if (rdfDtype != null) { graphs[graphID].AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFTypedLiteral(RDFModelUtilities.ASCII_To_Unicode(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText)), RDFModelUtilities.GetDatatypeFromString(rdfDtype.Value)))); } else { throw new RDFModelException(" found typed literal without required \"datatype\" attribute."); } } else { throw new RDFModelException(" found typed literal without required \"datatype\" attribute."); } } #endregion #endregion #region exception //Object is not valid: exception must be raised else { throw new RDFModelException("object (" + triple.ChildNodes[2].Name + ") of \"<triple>\" element is neither \"<uri>\" or \"<id>\" or \"<plainLiteral>\" or \"<typedLiteral>\"."); } #endregion } #endregion #region exception else { throw new RDFModelException("found a TriX element (" + triple.Name + ") which is neither \"<uri>\" or \"<triple>\", or is a \"<triple>\" without the required 3 childs."); } #endregion } #endregion } #endregion #region graphs merging foreach (var graph in graphs) { result.MergeGraph(graph.Value); } #endregion } #endregion } } return(result); #endregion } catch (Exception ex) { throw new RDFModelException("Cannot deserialize TriX because: " + ex.Message, ex); } }
/// <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); } }
/// <summary> /// Deserializes the given N-Triples stream to a graph. /// </summary> internal static RDFGraph Deserialize(Stream inputStream) { Int64 ntripleIndex = 0; try { #region deserialize using (StreamReader sr = new StreamReader(inputStream, Encoding.ASCII)) { RDFGraph result = new RDFGraph(); String ntriple = String.Empty; String[] tokens = new String[3]; RDFResource S = null; RDFResource P = null; RDFResource O = null; RDFLiteral L = null; while ((ntriple = sr.ReadLine()) != null) { ntripleIndex++; #region sanitize & tokenize //Cleanup previous data S = null; tokens[0] = String.Empty; P = null; tokens[1] = String.Empty; O = null; L = null; tokens[2] = String.Empty; //Preliminary sanitizations: clean trailing space-like chars ntriple = ntriple.Trim(new Char[] { ' ', '\t', '\r', '\n' }); //Skip empty or comment lines if (ntriple == String.Empty || ntriple.StartsWith("#")) { continue; } //Tokenizes the sanitized triple tokens = TokenizeNTriple(ntriple); #endregion #region subj String subj = tokens[0].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }) .Replace("_:", "bnode:"); S = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(subj)); #endregion #region pred String pred = tokens[1].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }); P = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(pred)); #endregion #region object if (tokens[2].StartsWith("<") || tokens[2].StartsWith("bnode:") || tokens[2].StartsWith("_:")) { String obj = tokens[2].TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }) .Replace("_:", "bnode:") .Trim(new Char[] { ' ', '\n', '\t', '\r' }); O = new RDFResource(RDFModelUtilities.ASCII_To_Unicode(obj)); } #endregion #region literal else { #region sanitize tokens[2] = regexSqt.Replace(tokens[2], String.Empty); tokens[2] = regexEqt.Replace(tokens[2], String.Empty); tokens[2] = tokens[2].Replace("\\\\", "\\") .Replace("\\\"", "\"") .Replace("\\n", "\n") .Replace("\\t", "\t") .Replace("\\r", "\r"); tokens[2] = RDFModelUtilities.ASCII_To_Unicode(tokens[2]); #endregion #region plain literal if (!tokens[2].Contains("^^") || tokens[2].EndsWith("^^") || tokens[2].Substring(tokens[2].LastIndexOf("^^", StringComparison.Ordinal) + 2, 1) != "<") { if (regexLPL.Match(tokens[2]).Success) { tokens[2] = tokens[2].Replace("\"@", "@"); String pLitValue = tokens[2].Substring(0, tokens[2].LastIndexOf("@", StringComparison.Ordinal)); String pLitLang = tokens[2].Substring(tokens[2].LastIndexOf("@", StringComparison.Ordinal) + 1); L = new RDFPlainLiteral(HttpUtility.HtmlDecode(pLitValue), pLitLang); } else { L = new RDFPlainLiteral(HttpUtility.HtmlDecode(tokens[2])); } } #endregion #region typed literal else { tokens[2] = tokens[2].Replace("\"^^", "^^"); String tLitValue = tokens[2].Substring(0, tokens[2].LastIndexOf("^^", StringComparison.Ordinal)); String tLitDatatype = tokens[2].Substring(tokens[2].LastIndexOf("^^", StringComparison.Ordinal) + 2) .TrimStart(new Char[] { '<' }) .TrimEnd(new Char[] { '>' }); RDFModelEnums.RDFDatatypes dt = RDFModelUtilities.GetDatatypeFromString(tLitDatatype); L = new RDFTypedLiteral(HttpUtility.HtmlDecode(tLitValue), dt); } #endregion } #endregion #region addtriple if (O != null) { result.AddTriple(new RDFTriple(S, P, O)); } else { result.AddTriple(new RDFTriple(S, P, L)); } #endregion } return(result); } #endregion } catch (Exception ex) { throw new RDFModelException("Cannot deserialize N-Triples (line " + ntripleIndex + ") because: " + ex.Message, ex); } }
/// <summary> /// Given an element representing a RDF container, iterates on its constituent elements /// to build its standard reification triples. /// </summary> internal static void ParseContainerElements(RDFModelEnums.RDFContainerType contType, XmlNode container, RDFResource subj, RDFResource pred, RDFGraph result) { //Attach the container as the blank object of the current pred RDFResource obj = new RDFResource(); result.AddTriple(new RDFTriple(subj, pred, obj)); //obj -> rdf:type -> rdf:[Bag|Seq|Alt] switch (contType) { case RDFModelEnums.RDFContainerType.Bag: result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.BAG)); break; case RDFModelEnums.RDFContainerType.Seq: result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.SEQ)); break; default: result.AddTriple(new RDFTriple(obj, RDFVocabulary.RDF.TYPE, RDFVocabulary.RDF.ALT)); break; } //Iterate on the container items if (container.HasChildNodes) { IEnumerator elems = container.ChildNodes.GetEnumerator(); List <String> elemVals = new List <String>(); while (elems != null && elems.MoveNext()) { XmlNode elem = (XmlNode)elems.Current; XmlAttribute elemUri = GetRdfResourceAttribute(elem); #region Container Resource Item //This is a container of resources if (elemUri != null) { //Sanitize eventual blank node value detected by presence of "nodeID" attribute if (elemUri.LocalName.Equals("nodeID", StringComparison.Ordinal)) { if (!elemUri.Value.StartsWith("bnode:")) { elemUri.Value = "bnode:" + elemUri.Value; } } //obj -> rdf:_N -> VALUE if (contType == RDFModelEnums.RDFContainerType.Alt) { if (!elemVals.Contains(elemUri.Value)) { elemVals.Add(elemUri.Value); result.AddTriple(new RDFTriple(obj, new RDFResource(RDFVocabulary.RDF.BASE_URI + elem.LocalName), new RDFResource(elemUri.Value))); } } else { result.AddTriple(new RDFTriple(obj, new RDFResource(RDFVocabulary.RDF.BASE_URI + elem.LocalName), new RDFResource(elemUri.Value))); } } #endregion #region Container Literal Item //This is a container of literals else { //Parse the literal contained in the item RDFLiteral literal = null; XmlAttribute attr = GetRdfDatatypeAttribute(elem); if (attr != null) { literal = new RDFTypedLiteral(elem.InnerText, RDFModelUtilities.GetDatatypeFromString(attr.InnerText)); } else { attr = GetXmlLangAttribute(elem); literal = new RDFPlainLiteral(elem.InnerText, (attr != null ? attr.InnerText : String.Empty)); } //obj -> rdf:_N -> VALUE if (contType == RDFModelEnums.RDFContainerType.Alt) { if (!elemVals.Contains(literal.ToString())) { elemVals.Add(literal.ToString()); result.AddTriple(new RDFTriple(obj, new RDFResource(RDFVocabulary.RDF.BASE_URI + elem.LocalName), literal)); } } else { result.AddTriple(new RDFTriple(obj, new RDFResource(RDFVocabulary.RDF.BASE_URI + elem.LocalName), literal)); } } #endregion } } }
/// <summary> /// Deserializes the given Xml stream to a graph. /// </summary> internal static RDFGraph Deserialize(Stream inputStream) { try { #region deserialize XmlReaderSettings xrs = new XmlReaderSettings(); xrs.IgnoreComments = true; xrs.DtdProcessing = DtdProcessing.Ignore; RDFGraph result = new RDFGraph(); using (XmlReader xr = XmlReader.Create(new StreamReader(inputStream, Encoding.UTF8), xrs)) { #region load XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xr); #endregion #region root //Prepare the namespace table for the Xml selections var nsMgr = new XmlNamespaceManager(new NameTable()); nsMgr.AddNamespace(RDFVocabulary.RDF.PREFIX, RDFVocabulary.RDF.BASE_URI); //Select "rdf:RDF" root node XmlNode rdfRDF = GetRdfRootNode(xmlDoc, nsMgr); #endregion #region prefixes //Select "xmlns" attributes and try to add them to the namespace register var xmlnsAttrs = GetXmlnsNamespaces(rdfRDF, nsMgr); //Try to get the "xml:base" attribute, which is needed to resolve eventual relative #IDs in "rdf:about" nodes //If it is not found, set it to the graph Uri Uri xmlBase = null; if (xmlnsAttrs != null && xmlnsAttrs.Count > 0) { var xmlBaseAttr = (rdfRDF.Attributes["xml:base"] ?? rdfRDF.Attributes["xmlns"]); if (xmlBaseAttr != null) { xmlBase = RDFModelUtilities.GetUriFromString(xmlBaseAttr.Value); } } //Always keep in synch the Context and the xmlBase if (xmlBase != null) { result.SetContext(xmlBase); } else { xmlBase = result.Context; } #endregion #region elements //Parse resource elements, which are the childs of root node and represent the subjects if (rdfRDF.HasChildNodes) { var subjNodesEnum = rdfRDF.ChildNodes.GetEnumerator(); while (subjNodesEnum != null && subjNodesEnum.MoveNext()) { #region subj //Get the current resource node XmlNode subjNode = (XmlNode)subjNodesEnum.Current; RDFResource subj = GetSubjectNode(subjNode, xmlBase, result); if (subj == null) { continue; } #endregion #region predObjList //Parse pred elements, which are the childs of subj element if (subjNode.HasChildNodes) { IEnumerator predNodesEnum = subjNode.ChildNodes.GetEnumerator(); while (predNodesEnum != null && predNodesEnum.MoveNext()) { //Get the current pred node RDFResource pred = null; XmlNode predNode = (XmlNode)predNodesEnum.Current; if (predNode.NamespaceURI == String.Empty) { pred = new RDFResource(xmlBase + predNode.LocalName); } else { pred = (predNode.LocalName.StartsWith("autoNS") ? new RDFResource(predNode.NamespaceURI) : new RDFResource(predNode.NamespaceURI + predNode.LocalName)); } #region object //Check if there is a "rdf:about" or a "rdf:resource" attribute XmlAttribute rdfObject = (GetRdfAboutAttribute(predNode) ?? GetRdfResourceAttribute(predNode)); if (rdfObject != null) { //Attribute found, but we must check if it is "rdf:ID", "rdf:nodeID" or a relative Uri String rdfObjectValue = ResolveRelativeNode(rdfObject, xmlBase); RDFResource obj = new RDFResource(rdfObjectValue); result.AddTriple(new RDFTriple(subj, pred, obj)); continue; } #endregion #region typed literal //Check if there is a "rdf:datatype" attribute XmlAttribute rdfDatatype = GetRdfDatatypeAttribute(predNode); if (rdfDatatype != null) { RDFModelEnums.RDFDatatype dt = RDFModelUtilities.GetDatatypeFromString(rdfDatatype.Value); RDFTypedLiteral tLit = new RDFTypedLiteral(HttpUtility.HtmlDecode(predNode.InnerText), dt); result.AddTriple(new RDFTriple(subj, pred, tLit)); continue; } //Check if there is a "rdf:parseType=Literal" attribute XmlAttribute parseLiteral = GetParseTypeLiteralAttribute(predNode); if (parseLiteral != null) { RDFTypedLiteral tLit = new RDFTypedLiteral(HttpUtility.HtmlDecode(predNode.InnerXml), RDFModelEnums.RDFDatatype.RDFS_LITERAL); result.AddTriple(new RDFTriple(subj, pred, tLit)); continue; } #endregion #region plain literal //Check if there is a "xml:lang" attribute, or if a unique textual child XmlAttribute xmlLang = GetXmlLangAttribute(predNode); if (xmlLang != null || (predNode.HasChildNodes && predNode.ChildNodes.Count == 1 && predNode.ChildNodes[0].NodeType == XmlNodeType.Text)) { RDFPlainLiteral pLit = new RDFPlainLiteral(HttpUtility.HtmlDecode(predNode.InnerText), (xmlLang != null ? xmlLang.Value : String.Empty)); result.AddTriple(new RDFTriple(subj, pred, pLit)); continue; } #endregion #region collection //Check if there is a "rdf:parseType=Collection" attribute XmlAttribute rdfCollect = GetParseTypeCollectionAttribute(predNode); if (rdfCollect != null) { ParseCollectionElements(xmlBase, predNode, subj, pred, result); continue; } #endregion #region container //Check if there is a "rdf:[Bag|Seq|Alt]" child node XmlNode container = GetContainerNode(predNode); if (container != null) { //Distinguish the right type of RDF container to build if (container.LocalName.Equals(RDFVocabulary.RDF.PREFIX + ":Bag", StringComparison.Ordinal) || container.LocalName.Equals("Bag", StringComparison.Ordinal)) { ParseContainerElements(RDFModelEnums.RDFContainerType.Bag, container, subj, pred, result); } else if (container.LocalName.Equals(RDFVocabulary.RDF.PREFIX + ":Seq", StringComparison.Ordinal) || container.LocalName.Equals("Seq", StringComparison.Ordinal)) { ParseContainerElements(RDFModelEnums.RDFContainerType.Seq, container, subj, pred, result); } else if (container.LocalName.Equals(RDFVocabulary.RDF.PREFIX + ":Alt", StringComparison.Ordinal) || container.LocalName.Equals("Alt", StringComparison.Ordinal)) { ParseContainerElements(RDFModelEnums.RDFContainerType.Alt, container, subj, pred, result); } } #endregion } } #endregion } } #endregion } return(result); #endregion } catch (Exception ex) { throw new RDFModelException("Cannot deserialize Xml because: " + ex.Message, ex); } }
/// <summary> /// Deserializes the given TriX stream to a graph. /// </summary> internal static RDFGraph Deserialize(Stream inputStream) { try { #region deserialize XmlReaderSettings xrs = new XmlReaderSettings(); xrs.IgnoreComments = true; xrs.DtdProcessing = DtdProcessing.Ignore; RDFGraph result = new RDFGraph(); using (XmlReader xr = XmlReader.Create(new StreamReader(inputStream, Encoding.UTF8), xrs)) { #region load XmlDocument trixDoc = new XmlDocument(); trixDoc.Load(xr); #endregion #region graph if (trixDoc.DocumentElement != null) { if (trixDoc.DocumentElement.ChildNodes.Count > 1) { throw new Exception(" given TriX file seems to encode more than one graph."); } var graphEnum = trixDoc.DocumentElement.ChildNodes.GetEnumerator(); while (graphEnum != null && graphEnum.MoveNext()) { XmlNode graph = (XmlNode)graphEnum.Current; if (!graph.Name.Equals("graph", StringComparison.Ordinal)) { throw new Exception(" a \"<graph>\" element was expected, instead of unrecognized \"<" + graph.Name + ">\"."); } #region triple var encodedUris = 0; var tripleEnum = graph.ChildNodes.GetEnumerator(); while (tripleEnum != null && tripleEnum.MoveNext()) { XmlNode triple = (XmlNode)tripleEnum.Current; #region uri if (triple.Name.Equals("uri", StringComparison.Ordinal)) { encodedUris++; if (encodedUris > 1) { throw new Exception(" given file encodes a graph with more than one \"<uri>\" element."); } result.SetContext(RDFModelUtilities.GetUriFromString(triple.ChildNodes[0].InnerText)); } #endregion #region triple else if (triple.Name.Equals("triple", StringComparison.Ordinal) && triple.ChildNodes.Count == 3) { #region subj //Subject is a resource ("<uri>") or a blank node ("<id>") if (triple.ChildNodes[0].Name.Equals("uri", StringComparison.Ordinal) || triple.ChildNodes[0].Name.Equals("id", StringComparison.Ordinal)) { //Sanitize eventual blank node value if (triple.ChildNodes[0].Name.Equals("id", StringComparison.Ordinal)) { if (!triple.ChildNodes[0].InnerText.StartsWith("bnode:")) { triple.ChildNodes[0].InnerText = "bnode:" + triple.ChildNodes[0].InnerText.Replace("_:", String.Empty); } } } //Subject is not valid: exception must be raised else { throw new RDFModelException("subject (" + triple.ChildNodes[0].Name + ") of \"<triple>\" element is neither \"<uri>\" or \"<id>\"."); } #endregion #region pred //Predicate is not valid: exception must be raised if (!triple.ChildNodes[1].Name.Equals("uri", StringComparison.Ordinal)) { throw new RDFModelException("predicate (" + triple.ChildNodes[1].Name + ") of \"<triple>\" element must be \"<uri>\"."); } #endregion #region object //Object is a resource ("<uri>") or a blank node ("<id>") if (triple.ChildNodes[2].Name.Equals("uri", StringComparison.Ordinal) || triple.ChildNodes[2].Name.Equals("id", StringComparison.Ordinal)) { //Sanitize eventual blank node value if (triple.ChildNodes[2].Name.Equals("id", StringComparison.Ordinal)) { if (!triple.ChildNodes[2].InnerText.StartsWith("bnode:")) { triple.ChildNodes[2].InnerText = "bnode:" + triple.ChildNodes[2].InnerText.Replace("_:", String.Empty); } } result.AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFResource(triple.ChildNodes[2].InnerText))); } #endregion #region literal #region plain literal else if (triple.ChildNodes[2].Name.Equals("plainLiteral")) { if (triple.ChildNodes[2].Attributes != null && triple.ChildNodes[2].Attributes.Count > 0) { XmlAttribute xmlLang = triple.ChildNodes[2].Attributes[RDFVocabulary.XML.PREFIX + ":lang"]; if (xmlLang != null) { //Plain literal with language result.AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText), xmlLang.Value))); } else { //Plain literal without language result.AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText)))); } } else { //Plain literal without language result.AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFPlainLiteral(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText)))); } } #endregion #region typed literal else if (triple.ChildNodes[2].Name.Equals("typedLiteral", StringComparison.Ordinal)) { if (triple.ChildNodes[2].Attributes != null && triple.ChildNodes[2].Attributes.Count > 0) { XmlAttribute rdfDtype = triple.ChildNodes[2].Attributes["datatype"]; if (rdfDtype != null) { result.AddTriple(new RDFTriple(new RDFResource(triple.ChildNodes[0].InnerText), new RDFResource(triple.ChildNodes[1].InnerText), new RDFTypedLiteral(HttpUtility.HtmlDecode(triple.ChildNodes[2].InnerText), RDFModelUtilities.GetDatatypeFromString(rdfDtype.Value)))); } else { throw new Exception(" found typed literal without required \"datatype\" attribute."); } } else { throw new Exception(" found typed literal without required \"datatype\" attribute."); } } #endregion #endregion #region exception //Object is not valid: exception must be raised else { throw new RDFModelException("object (" + triple.ChildNodes[2].Name + ") of \"<triple>\" element is neither \"<uri>\" or \"<id>\" or \"<plainLiteral>\" or \"<typedLiteral>\"."); } #endregion } #endregion #region exception else { throw new RDFModelException("found a TriX element (" + triple.Name + ") which is neither \"<uri>\" or \"<triple>\", or is a \"<triple>\" without the required 3 childs."); } #endregion } #endregion } } #endregion } return(result); #endregion } catch (Exception ex) { throw new RDFModelException("Cannot deserialize TriX because: " + ex.Message, ex); } }
private static void ParseShapeConstraints(DataRow shapesRow, RDFGraph graph, RDFShape shape) { //sh:and if (!shapesRow.IsNull("?AND")) { RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?AND")); if (reifSubj is RDFResource) { RDFAndConstraint andConstraint = new RDFAndConstraint(); RDFCollection andColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, RDFModelEnums.RDFTripleFlavors.SPO); andColl.Items.ForEach(item => { andConstraint.AddShape((RDFResource)item); }); shape.AddConstraint(andConstraint); } } //sh:class if (!shapesRow.IsNull("?CLASS")) { RDFPatternMember cls = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?CLASS")); if (cls is RDFResource) { shape.AddConstraint(new RDFClassConstraint((RDFResource)cls)); } } //sh:closed if (!shapesRow.IsNull("?CLOSED")) { RDFPatternMember closed = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?CLOSED")); if (closed is RDFTypedLiteral && ((RDFTypedLiteral)closed).HasBooleanDatatype()) { RDFClosedConstraint closedConstraint = new RDFClosedConstraint(Boolean.Parse(((RDFTypedLiteral)closed).Value)); //sh:ignoredProperties RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?IGNOREDPROPERTIES")); if (reifSubj is RDFResource) { RDFCollection ignoredPropsColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, RDFModelEnums.RDFTripleFlavors.SPO); ignoredPropsColl.Items.ForEach(item => { closedConstraint.AddIgnoredProperty((RDFResource)item); }); } shape.AddConstraint(closedConstraint); } } //sh:datatype if (!shapesRow.IsNull("?DATATYPE")) { RDFPatternMember datatype = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?DATATYPE")); if (datatype is RDFResource) { shape.AddConstraint(new RDFDatatypeConstraint(RDFModelUtilities.GetDatatypeFromString(datatype.ToString()))); } } //sh:disjoint if (!shapesRow.IsNull("?DISJOINT")) { RDFPatternMember disjpred = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?DISJOINT")); if (disjpred is RDFResource) { shape.AddConstraint(new RDFDisjointConstraint((RDFResource)disjpred)); } } //sh:equals if (!shapesRow.IsNull("?EQUALS")) { RDFPatternMember eqpred = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?EQUALS")); if (eqpred is RDFResource) { shape.AddConstraint(new RDFEqualsConstraint((RDFResource)eqpred)); } } //sh:hasValue if (!shapesRow.IsNull("?HASVALUE")) { RDFPatternMember value = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?HASVALUE")); if (value is RDFResource) { shape.AddConstraint(new RDFHasValueConstraint((RDFResource)value)); } else if (value is RDFLiteral) { shape.AddConstraint(new RDFHasValueConstraint((RDFLiteral)value)); } } //sh:in if (!shapesRow.IsNull("?IN")) { RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?IN")); if (reifSubj is RDFResource) { RDFModelEnums.RDFTripleFlavors inCollFlavor = RDFModelUtilities.DetectCollectionFlavorFromGraph(graph, (RDFResource)reifSubj); RDFCollection inColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, inCollFlavor); RDFInConstraint inConstraint = new RDFInConstraint(inColl.ItemType); inColl.Items.ForEach(item => { if (inColl.ItemType == RDFModelEnums.RDFItemTypes.Literal) { inConstraint.AddValue((RDFLiteral)item); } else { inConstraint.AddValue((RDFResource)item); } }); shape.AddConstraint(inConstraint); } } //sh:languageIn if (!shapesRow.IsNull("?LANGUAGEIN")) { RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?LANGUAGEIN")); if (reifSubj is RDFResource) { RDFCollection langTagsColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, RDFModelEnums.RDFTripleFlavors.SPL); shape.AddConstraint(new RDFLanguageInConstraint(langTagsColl.Select(x => x.ToString()).ToList())); } } //sh:lessThan if (!shapesRow.IsNull("?LESSTHAN")) { RDFPatternMember ltpred = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?LESSTHAN")); if (ltpred is RDFResource) { shape.AddConstraint(new RDFLessThanConstraint((RDFResource)ltpred)); } } //sh:lessThanOrEquals if (!shapesRow.IsNull("?LESSTHANOREQUALS")) { RDFPatternMember lteqpred = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?LESSTHANOREQUALS")); if (lteqpred is RDFResource) { shape.AddConstraint(new RDFLessThanOrEqualsConstraint((RDFResource)lteqpred)); } } //sh:maxCount if (!shapesRow.IsNull("?MAXCOUNT")) { RDFPatternMember maxCount = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MAXCOUNT")); if (maxCount is RDFTypedLiteral && ((RDFTypedLiteral)maxCount).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMaxCountConstraint(int.Parse(((RDFTypedLiteral)maxCount).Value))); } } //sh:maxExclusive if (!shapesRow.IsNull("?MAXEXCLUSIVE")) { RDFPatternMember value = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MAXEXCLUSIVE")); if (value is RDFResource) { shape.AddConstraint(new RDFMaxExclusiveConstraint((RDFResource)value)); } else if (value is RDFLiteral) { shape.AddConstraint(new RDFMaxExclusiveConstraint((RDFLiteral)value)); } } //sh:maxInclusive if (!shapesRow.IsNull("?MAXINCLUSIVE")) { RDFPatternMember value = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MAXINCLUSIVE")); if (value is RDFResource) { shape.AddConstraint(new RDFMaxInclusiveConstraint((RDFResource)value)); } else if (value is RDFLiteral) { shape.AddConstraint(new RDFMaxInclusiveConstraint((RDFLiteral)value)); } } //sh:maxLength if (!shapesRow.IsNull("?MAXLENGTH")) { RDFPatternMember maxLength = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MAXLENGTH")); if (maxLength is RDFTypedLiteral && ((RDFTypedLiteral)maxLength).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMaxLengthConstraint(int.Parse(((RDFTypedLiteral)maxLength).Value))); } } //sh:minCount if (!shapesRow.IsNull("?MINCOUNT")) { RDFPatternMember minCount = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MINCOUNT")); if (minCount is RDFTypedLiteral && ((RDFTypedLiteral)minCount).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMinCountConstraint(int.Parse(((RDFTypedLiteral)minCount).Value))); } } //sh:minExclusive if (!shapesRow.IsNull("?MINEXCLUSIVE")) { RDFPatternMember value = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MINEXCLUSIVE")); if (value is RDFResource) { shape.AddConstraint(new RDFMinExclusiveConstraint((RDFResource)value)); } else if (value is RDFLiteral) { shape.AddConstraint(new RDFMinExclusiveConstraint((RDFLiteral)value)); } } //sh:minInclusive if (!shapesRow.IsNull("?MININCLUSIVE")) { RDFPatternMember value = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MININCLUSIVE")); if (value is RDFResource) { shape.AddConstraint(new RDFMinInclusiveConstraint((RDFResource)value)); } else if (value is RDFLiteral) { shape.AddConstraint(new RDFMinInclusiveConstraint((RDFLiteral)value)); } } //sh:minLength if (!shapesRow.IsNull("?MINLENGTH")) { RDFPatternMember minLength = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?MINLENGTH")); if (minLength is RDFTypedLiteral && ((RDFTypedLiteral)minLength).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { shape.AddConstraint(new RDFMinLengthConstraint(int.Parse(((RDFTypedLiteral)minLength).Value))); } } //sh:node if (!shapesRow.IsNull("?NODE")) { RDFPatternMember nodeshapeUri = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?NODE")); if (nodeshapeUri is RDFResource) { shape.AddConstraint(new RDFNodeConstraint((RDFResource)nodeshapeUri)); } } //sh:nodeKind if (!shapesRow.IsNull("?NODEKIND")) { RDFPatternMember nodeKind = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?NODEKIND")); if (nodeKind is RDFResource) { if (nodeKind.Equals(RDFVocabulary.SHACL.BLANK_NODE)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNode)); } else if (nodeKind.Equals(RDFVocabulary.SHACL.BLANK_NODE_OR_IRI)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNodeOrIRI)); } else if (nodeKind.Equals(RDFVocabulary.SHACL.BLANK_NODE_OR_LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.BlankNodeOrLiteral)); } else if (nodeKind.Equals(RDFVocabulary.SHACL.IRI)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.IRI)); } else if (nodeKind.Equals(RDFVocabulary.SHACL.IRI_OR_LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.IRIOrLiteral)); } else if (nodeKind.Equals(RDFVocabulary.SHACL.LITERAL)) { shape.AddConstraint(new RDFNodeKindConstraint(RDFValidationEnums.RDFNodeKinds.Literal)); } } } //sh:not if (!shapesRow.IsNull("?NOT")) { RDFPatternMember notshapeUri = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?NOT")); if (notshapeUri is RDFResource) { shape.AddConstraint(new RDFNotConstraint((RDFResource)notshapeUri)); } } //sh:or if (!shapesRow.IsNull("?OR")) { RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?OR")); if (reifSubj is RDFResource) { RDFOrConstraint orConstraint = new RDFOrConstraint(); RDFCollection orColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, RDFModelEnums.RDFTripleFlavors.SPO); orColl.Items.ForEach(item => { orConstraint.AddShape((RDFResource)item); }); shape.AddConstraint(orConstraint); } } //sh:pattern if (!shapesRow.IsNull("?PATTERN")) { RDFPatternMember regexPattern = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?PATTERN")); if (regexPattern is RDFTypedLiteral && ((RDFTypedLiteral)regexPattern).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_STRING)) { //sh:flags RegexOptions regexOptions = RegexOptions.None; if (!shapesRow.IsNull("?FLAGS")) { RDFPatternMember regexFlags = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?FLAGS")); if (regexFlags is RDFTypedLiteral && ((RDFTypedLiteral)regexFlags).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_STRING)) { if (((RDFTypedLiteral)regexFlags).Value.Contains("i")) { regexOptions |= RegexOptions.IgnoreCase; } if (((RDFTypedLiteral)regexFlags).Value.Contains("s")) { regexOptions |= RegexOptions.Singleline; } if (((RDFTypedLiteral)regexFlags).Value.Contains("m")) { regexOptions |= RegexOptions.Multiline; } if (((RDFTypedLiteral)regexFlags).Value.Contains("x")) { regexOptions |= RegexOptions.IgnorePatternWhitespace; } } } shape.AddConstraint(new RDFPatternConstraint(new Regex(((RDFTypedLiteral)regexPattern).Value, regexOptions))); } } //sh:property if (!shapesRow.IsNull("?PROPERTY")) { RDFPatternMember propertyshapeUri = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?PROPERTY")); if (propertyshapeUri is RDFResource) { shape.AddConstraint(new RDFPropertyConstraint((RDFResource)propertyshapeUri)); } } //sh:qualifiedValueShape if (!shapesRow.IsNull("?QUALIFIEDVALUESHAPE")) { RDFPatternMember qualifiedValueShapeUri = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?QUALIFIEDVALUESHAPE")); if (qualifiedValueShapeUri is RDFResource) { //sh:qualifiedMinCount int?qualifiedMinCountValue = null; if (!shapesRow.IsNull("?QUALIFIEDMINCOUNT")) { RDFPatternMember qualifiedMinCount = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?QUALIFIEDMINCOUNT")); if (qualifiedMinCount is RDFTypedLiteral && ((RDFTypedLiteral)qualifiedMinCount).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { qualifiedMinCountValue = int.Parse(((RDFTypedLiteral)qualifiedMinCount).Value); } } //sh:qualifiedMaxCount int?qualifiedMaxCountValue = null; if (!shapesRow.IsNull("?QUALIFIEDMAXCOUNT")) { RDFPatternMember qualifiedMaxCount = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?QUALIFIEDMAXCOUNT")); if (qualifiedMaxCount is RDFTypedLiteral && ((RDFTypedLiteral)qualifiedMaxCount).Datatype.Equals(RDFModelEnums.RDFDatatypes.XSD_INTEGER)) { qualifiedMaxCountValue = int.Parse(((RDFTypedLiteral)qualifiedMaxCount).Value); } } shape.AddConstraint(new RDFQualifiedValueShapeConstraint((RDFResource)qualifiedValueShapeUri, qualifiedMinCountValue, qualifiedMaxCountValue)); } } //sh:uniqueLang if (!shapesRow.IsNull("?UNIQUELANG")) { RDFPatternMember uniqueLang = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?UNIQUELANG")); if (uniqueLang is RDFTypedLiteral && ((RDFTypedLiteral)uniqueLang).HasBooleanDatatype()) { shape.AddConstraint(new RDFUniqueLangConstraint(Boolean.Parse(((RDFTypedLiteral)uniqueLang).Value))); } } //sh:xone if (!shapesRow.IsNull("?XONE")) { RDFPatternMember reifSubj = RDFQueryUtilities.ParseRDFPatternMember(shapesRow.Field <string>("?XONE")); if (reifSubj is RDFResource) { RDFXoneConstraint xoneConstraint = new RDFXoneConstraint(); RDFCollection xoneColl = RDFModelUtilities.DeserializeCollectionFromGraph(graph, (RDFResource)reifSubj, RDFModelEnums.RDFTripleFlavors.SPO); xoneColl.Items.ForEach(item => { xoneConstraint.AddShape((RDFResource)item); }); shape.AddConstraint(xoneConstraint); } } }