示例#1
0
        // this shouldn't be a
        // valid iri/bnode i
        // hope!
        // TODO: fill with default namespaces
        public virtual object Call(RdfDataset dataset)
        {
            foreach (var e in dataset.GetNamespaces().GetEnumerableSelf
                         ())
            {
                availableNamespaces[e.Value] = e.Key;
            }
            usedNamespaces = new HashSet <string>();
            var refs = new JObject();
            var ttl  = new JObject();

            foreach (var graphName in dataset.Keys)
            {
                var localGraphName = graphName;
                var triples        = dataset.GetQuads(localGraphName);
                if ("@default".Equals(localGraphName))
                {
                    localGraphName = null;
                }

                // http://www.w3.org/TR/turtle/#unlabeled-bnodes
                // TODO: implement nesting for unlabled nodes
                // map of what the output should look like
                // subj (or [ if bnode) > pred > obj
                // > obj (set ref if IRI)
                // > pred > obj (set ref if bnode)
                // subj > etc etc etc
                // subjid -> [ ref, ref, ref ]
                var     prevSubject   = string.Empty;
                var     prevPredicate = string.Empty;
                JObject thisSubject   = null;
                JArray  thisPredicate = null;
                foreach (var triple in triples)
                {
                    var subject   = triple.GetSubject().GetValue();
                    var predicate = triple.GetPredicate().GetValue();
                    if (prevSubject.Equals(subject))
                    {
                        if (prevPredicate.Equals(predicate))
                        {
                        }
                        else
                        {
                            // nothing to do
                            // new predicate
                            if (thisSubject.ContainsKey(predicate))
                            {
                                thisPredicate = (JArray)thisSubject[predicate];
                            }
                            else
                            {
                                thisPredicate          = new JArray();
                                thisSubject[predicate] = thisPredicate;
                            }

                            prevPredicate = predicate;
                        }
                    }
                    else
                    {
                        // new subject
                        if (ttl.ContainsKey(subject))
                        {
                            thisSubject = (JObject)ttl[subject];
                        }
                        else
                        {
                            thisSubject  = new JObject();
                            ttl[subject] = thisSubject;
                        }

                        if (thisSubject.ContainsKey(predicate))
                        {
                            thisPredicate = (JArray)thisSubject[predicate];
                        }
                        else
                        {
                            thisPredicate          = new JArray();
                            thisSubject[predicate] = thisPredicate;
                        }

                        prevSubject   = subject;
                        prevPredicate = predicate;
                    }

                    if (triple.GetObject().IsLiteral())
                    {
                        thisPredicate.Add(triple.GetObject());
                    }
                    else
                    {
                        var o = triple.GetObject().GetValue();
                        if (o.StartsWith("_:"))
                        {
                            // add ref to o
                            if (!refs.ContainsKey(o))
                            {
                                refs[o] = new JArray();
                            }
                            ((JArray)refs[o]).Add(thisPredicate);
                        }

                        thisPredicate.Add(o);
                    }
                }
            }

            var collections = new JObject();
            var subjects    = new JArray(ttl.GetKeys());

            // find collections
            foreach (string subj in subjects)
            {
                var preds = (JObject)ttl[subj];
                if (preds != null && preds.ContainsKey(JsonLdConsts.RdfFirst))
                {
                    var col = new JArray();
                    collections[subj] = col;
                    while (true)
                    {
                        var first = (JArray)Collections.Remove(preds, JsonLdConsts.RdfFirst);
                        var o     = first[0];
                        col.Add(o);

                        // refs
                        if (refs.ContainsKey((string)o))
                        {
                            ((JArray)refs[(string)o]).Remove(first);
                            ((JArray)refs[(string)o]).Add(col);
                        }

                        var next = (string)Collections.Remove(preds, JsonLdConsts.RdfRest)[0
                                   ];
                        if (JsonLdConsts.RdfNil.Equals(next))
                        {
                            break;
                        }

                        // if collections already contains a value for "next", add
                        // it to this col and break out
                        if (collections.ContainsKey(next))
                        {
                            Collections.AddAll(col, (JArray)Collections.Remove(collections, next));
                            break;
                        }

                        preds = (JObject)Collections.Remove(ttl, next);
                        Collections.Remove(refs, next);
                    }
                }
            }

            // process refs (nesting referenced bnodes if only one reference to them
            // in the whole graph)
            foreach (var id in refs.GetKeys())
            {
                // skip items if there is more than one reference to them in the
                // graph
                if (((JArray)refs[id]).Count > 1)
                {
                    continue;
                }

                // otherwise embed them into the referenced location
                var @object = Collections.Remove(ttl, id);
                if (collections.ContainsKey(id))
                {
                    @object = new JObject();
                    var tmp = new JArray();
                    tmp.Add(Collections.Remove(collections, id));
                    ((JObject)@object)[ColsKey] = tmp;
                }

                var predicate = (JArray)refs[id][0];

                // replace the one bnode ref with the object
                predicate[predicate.LastIndexOf(id)] = @object;
            }

            // replace the rest of the collections
            foreach (var id_1 in collections.GetKeys())
            {
                var subj_1 = (JObject)ttl[id_1];
                if (!subj_1.ContainsKey(ColsKey))
                {
                    subj_1[ColsKey] = new JArray();
                }
                ((JArray)subj_1[ColsKey]).Add(collections[id_1]);
            }

            // build turtle output
            var output   = GenerateTurtle(ttl, 0, 0, false);
            var prefixes = string.Empty;

            foreach (var prefix in usedNamespaces)
            {
                var name = availableNamespaces[prefix];
                prefixes += "@prefix " + name + ": <" + prefix + "> .\n";
            }

            return((string.Empty.Equals(prefixes) ? string.Empty : prefixes + "\n") + output);
        }
 public virtual object Call(RdfDataset dataset)
 {
     return(RdfDatasetUtils.ToNQuads(dataset));
 }
示例#3
0
        /// <exception cref="JsonLD.Core.JsonLdError"></exception>
        public virtual RdfDataset Parse(JToken input)
        {
            if (!(input.Type == JTokenType.String))
            {
                throw new JsonLdError(JsonLdError.Error.InvalidInput,
                                      "Invalid input; Triple RDF Parser requires a string input"
                                      );
            }
            var result = new RdfDataset();
            var state  = new State(this, (string)input);

            while (!string.Empty.Equals(state.line))
            {
                // check if line is a directive
                var match = Regex.Directive.Matcher(state.line);
                if (match.Find())
                {
                    if (match.Group(1) != null || match.Group(4) != null)
                    {
                        var ns = match.Group(1) != null?match.Group(1) : match.Group(4);

                        var iri = match.Group(1) != null?match.Group(2) : match.Group(5);

                        if (!iri.Contains(":"))
                        {
                            iri = state.baseIri + iri;
                        }
                        iri = RdfDatasetUtils.Unescape(iri);
                        ValidateIRI(state, iri);
                        state.namespaces[ns] = iri;
                        result.SetNamespace(ns, iri);
                    }
                    else
                    {
                        var @base = match.Group(3) != null?match.Group(3) : match.Group(6);

                        @base = RdfDatasetUtils.Unescape(@base);
                        ValidateIRI(state, @base);
                        if ([email protected](":"))
                        {
                            state.baseIri = state.baseIri + @base;
                        }
                        else
                        {
                            state.baseIri = @base;
                        }
                    }

                    state.AdvanceLinePosition(match.Group(0).Length);
                    continue;
                }

                if (state.curSubject == null)
                {
                    // we need to match a subject
                    match = Regex.Subject.Matcher(state.line);
                    if (match.Find())
                    {
                        string iri;
                        if (match.Group(1) != null)
                        {
                            // matched IRI
                            iri = RdfDatasetUtils.Unescape(match.Group(1));
                            if (!iri.Contains(":"))
                            {
                                iri = state.baseIri + iri;
                            }
                        }
                        else
                        {
                            if (match.Group(2) != null)
                            {
                                // matched NS:NAME
                                var ns   = match.Group(2);
                                var name = UnescapeReserved(match.Group(3));
                                iri = state.ExpandIRI(ns, name);
                            }
                            else
                            {
                                if (match.Group(4) != null)
                                {
                                    // match ns: only
                                    iri = state.ExpandIRI(match.Group(4), string.Empty);
                                }
                                else
                                {
                                    if (match.Group(5) != null)
                                    {
                                        iri = state.namer.GetName(match.Group(0).Trim());
                                    }
                                    else
                                    {
                                        iri = state.namer.GetName();
                                    }
                                }
                            }
                        }

                        // make sure IRI still matches an IRI after escaping
                        ValidateIRI(state, iri);
                        state.curSubject = iri;
                        state.AdvanceLinePosition(match.Group(0).Length);
                    }
                    else
                    {
                        // handle blank nodes
                        if (state.line.StartsWith("["))
                        {
                            var bnode = state.namer.GetName();
                            state.AdvanceLinePosition(1);
                            state.Push();
                            state.curSubject = bnode;
                        }
                        else
                        {
                            // handle collections
                            if (state.line.StartsWith("("))
                            {
                                var bnode = state.namer.GetName();

                                // so we know we want a predicate if the collection close
                                // isn't followed by a subject end
                                state.curSubject = bnode;
                                state.AdvanceLinePosition(1);
                                state.Push();
                                state.curSubject   = bnode;
                                state.curPredicate = JsonLdConsts.RdfFirst;
                            }
                            else
                            {
                                // make sure we have a subject already
                                throw new JsonLdError(JsonLdError.Error.ParseError,
                                                      "Error while parsing Turtle; missing expected subject. {line: "
                                                      + state.lineNumber + "position: " + state.linePosition + "}");
                            }
                        }
                    }
                }

                if (state.curPredicate == null)
                {
                    // match predicate
                    match = Regex.Predicate.Matcher(state.line);
                    if (match.Find())
                    {
                        var iri = string.Empty;
                        if (match.Group(1) != null)
                        {
                            // matched IRI
                            iri = RdfDatasetUtils.Unescape(match.Group(1));
                            if (!iri.Contains(":"))
                            {
                                iri = state.baseIri + iri;
                            }
                        }
                        else
                        {
                            if (match.Group(2) != null)
                            {
                                // matched NS:NAME
                                var ns   = match.Group(2);
                                var name = UnescapeReserved(match.Group(3));
                                iri = state.ExpandIRI(ns, name);
                            }
                            else
                            {
                                if (match.Group(4) != null)
                                {
                                    iri = state.ExpandIRI(match.Group(4), string.Empty);
                                }
                                else
                                {
                                    iri = JsonLdConsts.RdfType;
                                }
                            }
                        }

                        ValidateIRI(state, iri);
                        state.curPredicate = iri;
                        state.AdvanceLinePosition(match.Group(0).Length);
                    }
                    else
                    {
                        throw new JsonLdError(JsonLdError.Error.ParseError,
                                              "Error while parsing Turtle; missing expected predicate. {line: "
                                              + state.lineNumber + "position: " + state.linePosition + "}");
                    }
                }

                // expecting bnode or object
                // match BNODE values
                if (state.line.StartsWith("["))
                {
                    var bnode = state.namer.GetName();
                    result.AddTriple(state.curSubject, state.curPredicate, bnode);
                    state.AdvanceLinePosition(1);

                    // check for anonymous objects
                    if (state.line.StartsWith("]"))
                    {
                        state.AdvanceLinePosition(1);
                    }
                    else
                    {
                        // next we expect a statement or object separator
                        // otherwise we're inside the blank node
                        state.Push();
                        state.curSubject = bnode;

                        // next we expect a predicate
                        continue;
                    }
                }
                else
                {
                    // match collections
                    if (state.line.StartsWith("("))
                    {
                        state.AdvanceLinePosition(1);

                        // check for empty collection
                        if (state.line.StartsWith(")"))
                        {
                            state.AdvanceLinePosition(1);
                            result.AddTriple(state.curSubject, state.curPredicate, JsonLdConsts.RdfNil);
                        }
                        else
                        {
                            // next we expect a statement or object separator
                            // otherwise we're inside the collection
                            var bnode = state.namer.GetName();
                            result.AddTriple(state.curSubject, state.curPredicate, bnode);
                            state.Push();
                            state.curSubject   = bnode;
                            state.curPredicate = JsonLdConsts.RdfFirst;
                            continue;
                        }
                    }
                    else
                    {
                        // match object
                        match = Regex.Object.Matcher(state.line);
                        if (match.Find())
                        {
                            string iri = null;
                            if (match.Group(1) != null)
                            {
                                // matched IRI
                                iri = RdfDatasetUtils.Unescape(match.Group(1));
                                if (!iri.Contains(":"))
                                {
                                    iri = state.baseIri + iri;
                                }
                            }
                            else
                            {
                                if (match.Group(2) != null)
                                {
                                    // matched NS:NAME
                                    var ns   = match.Group(2);
                                    var name = UnescapeReserved(match.Group(3));
                                    iri = state.ExpandIRI(ns, name);
                                }
                                else
                                {
                                    if (match.Group(4) != null)
                                    {
                                        // matched ns:
                                        iri = state.ExpandIRI(match.Group(4), string.Empty);
                                    }
                                    else
                                    {
                                        if (match.Group(5) != null)
                                        {
                                            iri = state.namer.GetName(match.Group(0).Trim());
                                        }
                                    }
                                }
                            }

                            if (iri != null)
                            {
                                ValidateIRI(state, iri);

                                // we have a object
                                result.AddTriple(state.curSubject, state.curPredicate, iri);
                            }
                            else
                            {
                                // we have a literal
                                var    value    = match.Group(6);
                                string lang     = null;
                                string datatype = null;
                                if (value != null)
                                {
                                    // we have a string literal
                                    value = UnquoteString(value);
                                    value = RdfDatasetUtils.Unescape(value);
                                    lang  = match.Group(7);
                                    if (lang == null)
                                    {
                                        if (match.Group(8) != null)
                                        {
                                            datatype = RdfDatasetUtils.Unescape(match.Group(8));
                                            if (!datatype.Contains(":"))
                                            {
                                                datatype = state.baseIri + datatype;
                                            }
                                            ValidateIRI(state, datatype);
                                        }
                                        else
                                        {
                                            if (match.Group(9) != null)
                                            {
                                                datatype = state.ExpandIRI(match.Group(9), UnescapeReserved(match.Group(10)));
                                            }
                                            else
                                            {
                                                if (match.Group(11) != null)
                                                {
                                                    datatype = state.ExpandIRI(match.Group(11), string.Empty);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        datatype = JsonLdConsts.RdfLangstring;
                                    }
                                }
                                else
                                {
                                    if (match.Group(12) != null)
                                    {
                                        // integer literal
                                        value    = match.Group(12);
                                        datatype = JsonLdConsts.XsdDouble;
                                    }
                                    else
                                    {
                                        if (match.Group(13) != null)
                                        {
                                            // decimal literal
                                            value    = match.Group(13);
                                            datatype = JsonLdConsts.XsdDecimal;
                                        }
                                        else
                                        {
                                            if (match.Group(14) != null)
                                            {
                                                // double literal
                                                value    = match.Group(14);
                                                datatype = JsonLdConsts.XsdInteger;
                                            }
                                            else
                                            {
                                                if (match.Group(15) != null)
                                                {
                                                    // boolean literal
                                                    value    = match.Group(15);
                                                    datatype = JsonLdConsts.XsdBoolean;
                                                }
                                            }
                                        }
                                    }
                                }

                                result.AddTriple(state.curSubject, state.curPredicate, value, datatype, lang);
                            }

                            state.AdvanceLinePosition(match.Group(0).Length);
                        }
                        else
                        {
                            throw new JsonLdError(JsonLdError.Error.ParseError,
                                                  "Error while parsing Turtle; missing expected object or blank node. {line: "
                                                  + state.lineNumber + "position: " + state.linePosition + "}");
                        }
                    }
                }

                // close collection
                var collectionClosed = false;
                while (state.line.StartsWith(")"))
                {
                    if (!JsonLdConsts.RdfFirst.Equals(state.curPredicate))
                    {
                        throw new JsonLdError(JsonLdError.Error.ParseError,
                                              "Error while parsing Turtle; unexpected ). {line: "
                                              + state.lineNumber + "position: " + state.linePosition + "}");
                    }
                    result.AddTriple(state.curSubject, JsonLdConsts.RdfRest, JsonLdConsts.RdfNil);
                    state.Pop();
                    state.AdvanceLinePosition(1);
                    collectionClosed = true;
                }

                var expectDotOrPred = false;

                // match end of bnode
                if (state.line.StartsWith("]"))
                {
                    var bnode = state.curSubject;
                    state.Pop();
                    state.AdvanceLinePosition(1);
                    if (state.curSubject == null)
                    {
                        // this is a bnode as a subject and we
                        // expect either a . or a predicate
                        state.curSubject = bnode;
                        expectDotOrPred  = true;
                    }
                }

                // match list separator
                if (!expectDotOrPred && state.line.StartsWith(","))
                {
                    state.AdvanceLinePosition(1);

                    // now we expect another object/bnode
                    continue;
                }

                // match predicate end
                if (!expectDotOrPred)
                {
                    while (state.line.StartsWith(";"))
                    {
                        state.curPredicate = null;
                        state.AdvanceLinePosition(1);

                        // now we expect another predicate, or a dot
                        expectDotOrPred = true;
                    }
                }

                if (state.line.StartsWith("."))
                {
                    if (state.expectingBnodeClose)
                    {
                        throw new JsonLdError(JsonLdError.Error.ParseError,
                                              "Error while parsing Turtle; missing expected )\"]\". {line: "
                                              + state.lineNumber + "position: " + state.linePosition + "}");
                    }
                    state.curSubject   = null;
                    state.curPredicate = null;
                    state.AdvanceLinePosition(1);

                    // this can now be the end of the document.
                    continue;
                }

                if (expectDotOrPred)
                {
                    continue;
                }

                // if we're in a collection
                if (JsonLdConsts.RdfFirst.Equals(state.curPredicate))
                {
                    var bnode = state.namer.GetName();
                    result.AddTriple(state.curSubject, JsonLdConsts.RdfRest, bnode);
                    state.curSubject = bnode;
                    continue;
                }

                if (collectionClosed)
                {
                    continue;
                }

                // if we get here, we're missing a close statement
                throw new JsonLdError(JsonLdError.Error.ParseError,
                                      "Error while parsing Turtle; missing expected \"]\" \",\" \";\" or \".\". {line: "
                                      + state.lineNumber + "position: " + state.linePosition + "}");
            }

            return(result);
        }