Coder Social home page Coder Social logo

linked-data-dotnet / json-ld.net Goto Github PK

View Code? Open in Web Editor NEW
223.0 41.0 46.0 1.33 MB

A JSON-LD processor for .NET.

License: Apache License 2.0

C# 99.23% PowerShell 0.62% Dockerfile 0.16%
json-ld jsonld csharp c-sharp dotnet dotnet-core dotnetcore dotnetstandard

json-ld.net's Introduction

json-ld.net

NuGet Build Status codecov

Introduction

This library is an implementation of the JSON-LD specification in C#.

JSON, as specified in RFC7159, is a simple language for representing objects on the Web. Linked Data is a way of describing content across different documents or Web sites. Web resources are described using IRIs, and typically are dereferencable entities that may be used to find more information, creating a "Web of Knowledge". JSON-LD is intended to be a simple publishing method for expressing not only Linked Data in JSON, but for adding semantics to existing JSON.

JSON-LD is designed as a light-weight syntax that can be used to express Linked Data. It is primarily intended to be a way to express Linked Data in JavaScript and other Web-based programming environments. It is also useful when building interoperable Web Services and when storing Linked Data in JSON-based document storage engines. It is practical and designed to be as simple as possible, utilizing the large number of JSON parsers and existing code that is in use today. It is designed to be able to express key-value pairs, RDF data, RDFa data, Microformats data, and Microdata. That is, it supports every major Web-based structured data model in use today.

The syntax does not require many applications to change their JSON, but easily add meaning by adding context in a way that is either in-band or out-of-band. The syntax is designed to not disturb already deployed systems running on JSON, but provide a smooth migration path from plain JSON to semantically enhanced JSON. Finally, the format is intended to be fast to parse, fast to generate, stream-based and document-based processing compatible, and require a very small memory footprint in order to operate.

You can read more about JSON-LD on the JSON-LD website.

Conformance

This library aims to conform with the following:

The [JSON-LD Working Group][json-ld-wg] is now developing JSON-LD 1.1. Library updates to conform with newer specifications will happen as features stabilize and development time and resources permit.

The test runner is often updated to note or skip newer tests that are not yet supported.

Supported frameworks

  • .NET 4.0
  • .NET Standard 1.3 and 2.0
  • Portable .NET 4.5, Windows 8

Installation

dotnet CLI

dotnet new console
dotnet add package json-ld.net
using JsonLD.Core;
using Newtonsoft.Json.Linq;
using System;

namespace JsonLD.Demo
{
    internal class Program
    {
        private static void Main()
        {
            var json = "{'@context':{'test':'http://www.test.com/'},'test:hello':'world'}";
            var document = JObject.Parse(json);
            var expanded = JsonLdProcessor.Expand(document);
            Console.WriteLine(expanded);
        }
    }
}

Examples


Example data and context used throughout examples below:

doc.json

{
    "@id": "http://example.org/ld-experts",
    "http://schema.org/name": "LD Experts",
    "http://schema.org/member": [{
        "@type": "http://schema.org/Person",
        "http://schema.org/name": "Manu Sporny",
        "http://schema.org/url": {"@id": "http://manu.sporny.org/"},
        "http://schema.org/image": {"@id": "http://manu.sporny.org/images/manu.png"}
    }]
}

context.json

{
    "name": "http://schema.org/name",
    "member": "http://schema.org/member",
    "homepage": {"@id": "http://schema.org/url", "@type": "@id"},
    "image": {"@id": "http://schema.org/image", "@type": "@id"},
    "Person": "http://schema.org/Person",
    "@vocab": "http://example.org/",
    "@base": "http://example.org/"
}

Compact

Compaction is the process of applying a developer-supplied context to shorten IRIs to terms or compact IRIs, and JSON-LD values expressed in expanded form to simple values such as strings or numbers. Often this makes it simpler to work with a document as the data is expressed in application-specific terms. Compacted documents are also typically easier to read for humans.

var doc = JObject.Parse(_docJson);
var context = JObject.Parse(_contextJson);
var opts = new JsonLdOptions();
var compacted = JsonLdProcessor.Compact(doc, context, opts);
Console.WriteLine(compacted);

/*

Output:
{
    "@id": "ld-experts",
    "member": {
        "@type": "Person",
        "image": "http://manu.sporny.org/images/manu.png",
        "name": "Manu Sporny",
        "homepage": "http://manu.sporny.org/"
    },
    "name": "LD Experts",
    "@context": . . .
}

*/

Expand

Exapansion is the process of taking a JSON-LD document and applying a @context such that all IRIs, types, and values are expanded so that the @context is no longer necessary.

var expanded = JsonLdProcessor.Expand(compacted);
Console.WriteLine(expanded);

/*

Output:
[
    {
        "@id": "http://test.com/ld-experts",
        "http://schema.org/member": [
            {
                "http://schema.org/url": [
                    {
                        "@id": "http://manu.sporny.org/"
                    }
                ],
                "http://schema.org/image": [
                    {
                        "@id": "http://manu.sporny.org/images/manu.png"
                    }
                ],
                "http://schema.org/name": [
                    {
                        "@value": "Manu Sporny"
                    }
                ]
            }
        ],
        "http://schema.org/name": [
            {
                "@value": "LD Experts"
            }
        ]
    }
]

*/


*/

Flatten

Flattening collects all properties of a node in a single JSON object and labels all blank nodes with blank node identifiers. This ensures a shape of the data and consequently may drastically simplify the code required to process JSON-LD in certain applications.

var doc = JObject.Parse(_docJson);
var context = JObject.Parse(_contextJson);
var opts = new JsonLdOptions();
var flattened = JsonLdProcessor.Flatten(doc, context, opts);
Console.WriteLine(flattened);

/*

Output:
{
    "@context": . . .,
    "@graph": [
        {
            "@id": "_:b0",
            "@type": "Person",
            "image": "http://manu.sporny.org/images/manu.png",
            "name": "Manu Sporny",
            "homepage": "http://manu.sporny.org/"
        },
        {
            "@id": "ld-experts",
            "member": {
                "@id": "_:b0"
            },
            "name": "LD Experts"
        }
    ]
}

*/

Frame

Framing is used to shape the data in a JSON-LD document, using an example frame document which is used to both match the flattened data and show an example of how the resulting data should be shaped. Matching is performed by using properties present in the frame to find objects in the data that share common values. Matching can be done either using all properties present in the frame, or any property in the frame. By chaining together objects using matched property values, objects can be embedded within one another.

A frame also includes a context, which is used for compacting the resulting framed output.

For the framing example below, the framing document is defined as follows:

{
    "@context": {
        "name": "http://schema.org/name",
        "member": {"@id": "http://schema.org/member", "@type": "@id"},
        "homepage": {"@id": "http://schema.org/url", "@type": "@id"},
        "image": {"@id": "http://schema.org/image", "@type": "@id"},
        "Person": "http://schema.org/Person"
    },
    "@type": "Person"
}

And we use it like this:

var doc = JObject.Parse(_docJson);
var frame = JObject.Parse(_frameJson);
var opts = new JsonLdOptions();
var flattened = JsonLdProcessor.Frame(doc, frame, opts);
Console.WriteLine(flattened);

/*

Output:
{
    "@context": . . .,
    "@graph": [
        {
            "@id": "_:b0",
            "@type": "Person",
            "image": "http://manu.sporny.org/images/manu.png",
            "name": "Manu Sporny",
            "homepage": "http://manu.sporny.org/"
        }
    ]
}

*/

Normalize

Normalization (aka. canonicalization) converts the document into a graph of objects that is a canonical representation of the document that can be used for hashing, comparison, etc.

var doc = JObject.Parse(_docJson);
var opts = new JsonLdOptions();
var normalized = (RDFDataset)JsonLdProcessor.Normalize(doc, opts);
Console.WriteLine(normalized.Dump());

/*

Output:
@default
    subject
            type      blank node
            value     _:c14n0
    predicate
            type      IRI
            value     http://schema.org/image
    object
            type      IRI
            value     http://manu.sporny.org/images/manu.png
    ---
    subject
            type      blank node
            value     _:c14n0
    predicate
            type      IRI
            value     http://schema.org/name
    object
            type      literal
            value     Manu Sporny
            datatype  http://www.w3.org/2001/XMLSchema#string
    ---
    subject
            type      blank node
            value     _:c14n0
    predicate
            type      IRI
            value     http://schema.org/url
    object
            type      IRI
            value     http://manu.sporny.org/
    ---
    subject
            type      blank node
            value     _:c14n0
    predicate
            type      IRI
            value     http://www.w3.org/1999/02/22-rdf-syntax-ns#type
    object
            type      IRI
            value     http://schema.org/Person
    ---
    subject
            type      IRI
            value     http://example.org/ld-experts
    predicate
            type      IRI
            value     http://schema.org/member
    object
            type      blank node
            value     _:c14n0
    ---
    subject
            type      IRI
            value     http://example.org/ld-experts
    predicate
            type      IRI
            value     http://schema.org/name
    object
            type      literal
            value     LD Experts
            datatype  http://www.w3.org/2001/XMLSchema#string
    ---

*/

ToRDF

JSON-LD is a concrete RDF syntax as described in RDF 1.1 Concepts and Abstract Syntax. Hence, a JSON-LD document is both an RDF document and a JSON document and correspondingly represents an instance of an RDF data model. The procedure to deserialize a JSON-LD document to an RDF dataset (and, optionally, to RDF N-Quads) involves the following steps:

  1. Expand the JSON-LD document, removing any context; this ensures that properties, types, and values are given their full representation as IRIs and expanded values.
  2. Flatten the document, which turns the document into an array of node objects.
  3. Turn each node object into a series of RDF N-Quads.

The processor's ToRDF method carries out these steps for you, like this:

var doc = JObject.Parse(_docJson);
var opts = new JsonLdOptions();
var rdf = (RDFDataset)JsonLdProcessor.ToRDF(doc, opts);

var serialized = RDFDatasetUtils.ToNQuads(rdf); // serialize RDF to string
Console.WriteLine(serialized);

/*

Output:
<http://example.org/ld-experts> <http://schema.org/member> _:b0 .
<http://example.org/ld-experts> <http://schema.org/name> "LD Experts" .
_:b0 <http://schema.org/image> <http://manu.sporny.org/images/manu.png> .
_:b0 <http://schema.org/name> "Manu Sporny" .
_:b0 <http://schema.org/url> <http://manu.sporny.org/> .
_:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> .

*/

or using a custom RDF renderer object, like this:

private class JSONLDTripleCallback : IJSONLDTripleCallback
{
    public object Call(RDFDataset dataset) =>
        RDFDatasetUtils.ToNQuads(dataset); // serialize the RDF dataset as NQuads
}

internal static void Run()
{
    var doc = JObject.Parse(_docJson);
    var callback = new JSONLDTripleCallback();
    var serialized = JsonLdProcessor.ToRDF(doc, callback);
    Console.WriteLine(serialized);

    /*

    Output:
    <http://example.org/ld-experts> <http://schema.org/member> _:b0 .
    <http://example.org/ld-experts> <http://schema.org/name> "LD Experts" .
    _:b0 <http://schema.org/image> <http://manu.sporny.org/images/manu.png> .
    _:b0 <http://schema.org/name> "Manu Sporny" .
    _:b0 <http://schema.org/url> <http://manu.sporny.org/> .
    _:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://schema.org/Person> .

    */
}

FromRDF

Serialization from RDF N-Quads into JSON-LD can be thought of as the inverse of the last of the three steps described in summary Deserialization described in the ToRDF method documentation above. Serialization creates an expanded JSON-LD document closely matching the N-Quads from RDF, using a single node object for all N-Quads having a common subject, and a single property for those N-Quads also having a common predicate.

In practice, it looks like this:

the variable serialized is populated with RDF N-Quads values resulting from the code in the ToRDF example above

var opts = new JsonLdOptions();
var jsonld = JsonLdProcessor.FromRDF(serialized, opts);
Console.WriteLine(jsonld);

/*

Output:
[
    {
        "@id": "_:b0",
        "http://schema.org/image": [
            {
                "@id": "http://manu.sporny.org/images/manu.png"
            }
        ],
        "http://schema.org/name": [
            {
                "@value": "Manu Sporny"
            }
        ],
        "http://schema.org/url": [
            {
                "@id": "http://manu.sporny.org/"
            }
        ],
        "@type": [
            "http://schema.org/Person"
        ]
    },
    {
        "@id": "http://example.org/ld-experts",
        "http://schema.org/member": [
            {
                "@id": "_:b0"
            }
        ],
        "http://schema.org/name": [
            {
                "@value": "LD Experts"
            }
        ]
    }
]
*/

or using a custom RDF parser:

private class CustomRDFParser : IRDFParser
{
    public RDFDataset Parse(JToken input)
    {
        // by public decree, references to example.org are normalized to https going forward...
        var converted = ((string)input).Replace("http://example.org/", "https://example.org/");
        return RDFDatasetUtils.ParseNQuads(converted);
    }
}

internal static void Run()
{
    var parser = new CustomRDFParser();
    var jsonld = JsonLdProcessor.FromRDF(_serialized, parser);
    Console.WriteLine(jsonld);

    /*

    Output:
    [
        {
            "@id": "_:b0",
            "http://schema.org/image": [
                {
                    "@id": "http://manu.sporny.org/images/manu.png"
                }
            ],
            "http://schema.org/name": [
                {
                    "@value": "Manu Sporny"
                }
            ],
            "http://schema.org/url": [
                {
                    "@id": "http://manu.sporny.org/"
                }
            ],
            "@type": [
                "http://schema.org/Person"
            ]
        },
        {
            "@id": "https://example.org/ld-experts",
            "http://schema.org/member": [
                {
                    "@id": "_:b0"
                }
            ],
            "http://schema.org/name": [
                {
                    "@value": "LD Experts"
                }
            ]
        }
    ]
    */
}

Custom DocumentLoader

By replacing the default documentLoader object placed on the JsonLdProcessor, it is possible to alter the behaviour when retrieving a remote document (e.g. a context document) required to execute a given algorithm (e.g. Expansion).

public class CustomDocumentLoader : DocumentLoader
{
    private static readonly string _cachedExampleOrgContext = Res.ReadString("context.json");

    public override RemoteDocument LoadDocument(string url)
    {
        if (url == "http://example.org/context.jsonld") // we have this cached locally
        {
            var doc = new JObject(new JProperty("@context", JObject.Parse(_cachedExampleOrgContext)));
            return new RemoteDocument(url, doc);
        }
        else
        {
            return base.LoadDocument(url);
        }
    }
}

public static void Run()
{
    var doc = JObject.Parse(_docJson);
    var remoteContext = JObject.Parse("{'@context':'http://example.org/context.jsonld'}");
    var opts = new JsonLdOptions { documentLoader = new CustomDocumentLoader() };
    var compacted = JsonLdProcessor.Compact(doc, remoteContext, opts);
    Console.WriteLine(compacted);

    /*

    Output:
    {
        "@id": "http://example.org/ld-experts",
        "member": {
            "@type": "Person",
            "image": "http://manu.sporny.org/images/manu.png",
            "name": "Manu Sporny",
            "homepage": "http://manu.sporny.org/"
        },
        "name": "LD Experts"
    }

    */
}

Contributing

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Pull requests for json-ld.net are welcome, to get started install the latest tools for .NET Core:

Build and Tests

On Windows, you can execute build.ps1, which will create a nupkg and run tests for both .NET desktop and .NET Core.

On both Windows and all other supported operating systems, you can run dotnet build to build and dotnet test to run the tests.

Origin

This project began life as a Sharpen-based auto-port from jsonld-java.

Documentation for this library is in part drawn from https://github.com/linked-data-dotnet/json-ld.net

json-ld.net's People

Contributors

asbjornu avatar dependabot-preview[bot] avatar dependabot[bot] avatar dnllowe avatar dtivel avatar emgarten avatar goofballlogic avatar jtone123 avatar mergify[bot] avatar object avatar sblom avatar tpluscode avatar xivk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-ld.net's Issues

JsonLd to NQuads changes DataTime values to non-standard values

var jsonLdString = "..." // contains "2015-06-22T17:37:04.1656245+02:00"
var jsonLd = JSONUtils.FromString(jsonLdString); 
var nquads = (string) JsonLdProcessor.ToRDF(jsonLd, new NQuadTripleCallback()); // contains "06/22/2015 17:37:04"

I am using your library to convert json-ld to nquads but it changes xsd-datetime-format to something else. It should prevent the previous format or it should use a format that is compatible with the provided type ("http://www.w3.org/2001/XMLSchema#dateTime").

Extract from JSON-LD:

[...]
          "ns:date": {
            "@type": "xsd:dateTime",
            "@value": "2015-06-22T17:37:04.1656245+02:00"
          },
[...]

Extract from NQuad:

[...]
    <http://ns#EmailMessage-8259dce5-eb15-4dc8-bace-40c138fc594f> <http://ns#date> "06/22/2015 17:37:04"^^<http://www.w3.org/2001/XMLSchema#dateTime> <http://ns#EmailMessage-8259dce5-eb15-4dc8-bace-40c138fc594f> .
[...]

JsonLdUtils.DeepCompare(...): poor performance on large arrays

Version 1.0.4

JsonLD.Core.JsonLdUtils.DeepCompare(...) has poor performance when comparing large arrays. With the provided repro (below) it takes ~4 seconds to perform a deep comparison on two objects.

Repro:

using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using JsonLD.Core;
using Newtonsoft.Json.Linq;

class Program
{
    private static void Main()
    {
        try
        {
            Test();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }

    private static void Test()
    {
        var uri = new Uri("https://az635243.vo.msecnd.net/v3-catalog0/data/2018.06.27.19.19.02/test20180627163712.1.0.485.json");
        var request = WebRequest.CreateHttp(uri);
        JToken token1;
        JToken token2;

        using (var response = request.GetResponse())
        using (var stream = response.GetResponseStream())
        using (var reader = new StreamReader(stream))
        {
            var json = reader.ReadToEnd();

            token1 = JObject.Parse(json);
            token2 = JObject.Parse(json);
        }

        Test(() => JsonLdUtils.DeepCompare(token1, token2), times: 10);
    }

    private static void Test(Action action, int times)
    {
        var stopwatch = new Stopwatch();

        for (var i = 0; i < times; ++i)
        {
            stopwatch.Restart();

            action();

            Console.WriteLine(stopwatch.Elapsed.TotalSeconds);
        }
    }
}

Parsing ContentType is too restrictive

DocumentLoader::LoadDocument() tries to validate that the media type is JSON-LD. However, the check is too strict: it only passes if the content type is equal to "application/ld+json". This excludes other valid strings like "application/ld+json; charset=utf-8". Specifying the charset is very common for users who create their response messages using System.Net.Http.dll (e.g., using StringContent).

An easy fix is to replace equality check with "StartsWith()".

Support dependency-injection

The normal usage pattern for the library is to use the static JsonLdProcessor class. This works well for the stateless, static algorithms which make up the JSON-LD standard. However, it requires a consumer to create an injectable facade class in order to inject the APIs into consumers. e.g.

interface IJsonLdProcess {
    JObject Compact(JToken input, JToken context, JsonLdOptions opts);
}

class JsonLdProcess {
    JObject Compact(JToken input, JToken context, JsonLdOptions opts) {
        return JsonLdProcessor.Compact(input, context, opts);
    }
}

public class Consumer {

    private readonly JToken _context;
    private readonly IJsonLdProcess _jsonLdProcess;

    public Consumer(IJsonLdProcess jsonLdProcess, JToken context) {
        _jsonLdProcess = jsonLdProcess;
        _context = context;
    }

    public JObject Execute(JObject input) =>
        _jsonLdProcess.Compact(input, _context);
    }
}

Can we provide the functionality exposed by JsonLdProcessor as a non-static implementation of an interface which can be mocked for purposes of unit testing / decoration.

Tests failing due to json-ld.org changes -> https

Tests which use the remote document loading feature are failing for me:


    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0001", testname: "load JSON-LD document", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...], [...], [...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0002", testname: "load JSON document", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...], [...], [...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0003", testname: "load JSON document with extension-type", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...], [...], [...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0005", testname: "Load JSON-LD through 301 redirect", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = null, output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0006", testname: "Load JSON-LD through 303 redirect", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = null, output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0007", testname: "Load JSON-LD through 307 redirect", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = null, output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0009", testname: "load JSON-LD document with link", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0010", testname: "load JSON document with link", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
    JsonLD.Test.ConformanceTests.ConformanceTestPasses(id: "remote-doc-manifest.jsonld#t0011", testname: "load JSON document with extension-type with link", conformanceCase: ConformanceCase { context = null, error = null, frame = null, input = [[...]], output = [[...]], ... }) [FAIL]
      Returned JSON doesn't match expectations.
      Expected: True
      Actual:   False
      Stack Trace:
        ConformanceTests.cs(34,0): at JsonLD.Test.ConformanceTests.ConformanceTestPasses(String id, String testname, ConformanceCase conformanceCase)
  Finished:    json-ld.net.tests
=== TEST EXECUTION SUMMARY ===
   json-ld.net.tests  Total: 545, Errors: 0, Failed: 9, Skipped: 0, Time: 10.251s
Tests failed!!!

lists of objects don't appear to frame correctly

The following flattened and expanded JSON:

[
  {
    "@id": "http://tempuri.org/schema#sub0",
    "@type": [
      "http://tempuri.org/schema#Class"
    ],
    "http://tempuri.org/schema#prop0": [
      {
        "@list": [
          {
            "@id": "http://tempuri.org/schema#hello"
          },
          {
            "@id": "http://tempuri.org/schema#world"
          }
        ]
      }
    ]
  },
  {
    "@id": "_:autos1",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": [
      {
        "@id": "http://tempuri.org/schema#hello"
      }
    ],
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": [
      {
        "@id": "_:autos2"
      }
    ]
  },
  {
    "@id": "_:autos2",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": [
      {
        "@id": "http://tempuri.org/schema#world"
      }
    ],
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": [
      {
        "@id": "http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"
      }
    ]
  },
  {
    "@id": "http://tempuri.org/schema#hello",
    "http://tempuri.org/schema#prop1": [
      {
        "@value": "Hello"
      }
    ]
  },
  {
    "@id": "http://tempuri.org/schema#world",
    "http://tempuri.org/schema#prop1": [
      {
        "@value": "World"
      }
    ]
  }
]

With the frame:

{
    "@context" : { 
        "ns" : "http://tempuri.org/schema#",

        "prop0" : { "@container" : "@list" },

        "@vocab" : "http://tempuri.org/schema#"
    },
    "@type" : "ns:Class"
} 

Should produce a framed form like this, according to the json-ld playground

{
  "@context": {
    "ns": "http://tempuri.org/schema#",
    "prop0": {
      "@container": "@list"
    },
    "@vocab": "http://tempuri.org/schema#"
  },
  "@graph": [
    {
      "@id": "ns:sub0",
      "@type": "Class",
      "prop0": [
        {
          "@id": "ns:hello",
          "prop1": "Hello"
        },
        {
          "@id": "ns:world",
          "prop1": "World"
        }
      ]
    }
  ]
}

However it appears to drop the nested objects, just leaving their links

{
  "@id": "ns:sub0",
  "@type": "Class",
  "prop0": [
    {
      "@id": "ns:hello"
    },
    {
      "@id": "ns:world"
    }
  ],
  "@context": {
    "@vocab": "http://tempuri.org/schema#",
    "ns": "http://tempuri.org/schema#",
    "prop0": {
      "@id": "ns:prop0",
      "@container": "@list"
    }
  }
}

Version 1.0.7 is missing on nuget.org

Hi,

I want to use json-ld.net in my project on .net 3.0 however I cannot find the correct version.
On the nuget.org/json-ld.net the most recent version is 1.0.6.
This version have dependencies on release candidates (e.g. NETStandard.Library (>= 1.5.0-rc2-24027) which I do not want to use.
However, I found package version 1.0.7 on github.

Is there any reason it hasn't been published on nuget.org?

Thanks.

Support System.Text.Json

System.Text.Json is now built into .NET Core 3 and installable for .NET Standard 2.0+ (e.g. .NET framework 4.7.2+). Can we support this going foward (either instead of or in addition to Newtonsoft Json)

Examples missing

Would be nice if there was examples of usage, e.g. standalone or part of aspi.net webpi

Incorrect compaction

Hi

I've found a problem with how set of URIs are compacted. Here's how playgroud does it

In code I'm getting incorrect compated JSON. Well, it's correct but not correctly compacted still

{
  "languages": [
    {
      "@id": "langIso:tr"
    },
    {
      "@id": "langIso:en"
    }
  ]
}

It would seem that the library doesn't respect the "@type": "@id" in property definition in the @context

Release 1.0.6

Push a new release to update package metadata and include perf and scripting fixes

Evolve or Rewrite?

My understanding of the history of this library is that it was ported from the initial Java implementation. It was also built for standalone builds targeting multiple platforms when the tooling was a bit less sophisticated than it is these days.

As we consider supporting JSON-LD 1.1, should we evolve the current library to adopt modern .NET practices or attempt a rewrite?

No remote context on CoreCLR ?

A seemingly simple operation of retrieving a remote context document appears not to be supported on .NET Core for some reason????

From https://github.com/NuGet/json-ld.net/blob/master/src/json-ld.net/Core/DocumentLoader.cs#L15

namespace JsonLD.Core
{
    public class DocumentLoader
    {
        /// <exception cref="JsonLDNet.Core.JsonLdError"></exception>
        public virtual RemoteDocument LoadDocument(string url)
        {
#if !PORTABLE && !IS_CORECLR
            . . . snipped . . .
            return doc;
#else
            throw new PlatformNotSupportedException();
#endif
        }

Is this code being used in anger?

Control order of graph nodes and children nodes

My team and I have been using this library and it's made life much easier when working with quads and the rdf format. Thanks!

However, we have a need to return jsonld where order matters. But, the JsonLdApi.FromRDF method sorts properties by default. We need to be able to control when to sort the top-level graphs, the child nodes, or both.

For example, given the json below, we'd want to control whether nodes 1, 2, and 3 get sorted, and whether their children (objects 1, 2, and 3) are sorted. As of now, the JsonLdApi.FromRDF will always sort the graph nodes and children, losing the orignal order:

[
    {
        "@id": "http://example.org/node/3",
        "@graph": [
            {
                "@id": "http://example.org/object/3",
                "http://example.org/value": [
                    {
                        "@id": "n3-o3-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/1",
                "http://example.org/value": [
                    {
                        "@id": "n3-o1-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/2",
                "http://example.org/value": [
                    {
                        "@id": "n3-o2-value"
                    }
                ]
            }
        ]
    },
    {
        "@id": "http://example.org/node/1",
        "@graph": [
            {
                "@id": "http://example.org/object/3",
                "http://example.org/value": [
                    {
                        "@id": "n1-o3-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/1",
                "http://example.org/value": [
                    {
                        "@id": "n1-o1-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/2",
                "http://example.org/value": [
                    {
                        "@id": "n1-o2-value"
                    }
                ]
            }
        ]
    },
    {
        "@id": "http://example.org/node/2",
        "@graph": [
            {
                "@id": "http://example.org/object/3",
                "http://example.org/value": [
                    {
                        "@id": "n2-o3-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/1",
                "http://example.org/value": [
                    {
                        "@id": "n2-o1-value"
                    }
                ]
            },
            {
                "@id": "http://example.org/object/2",
                "http://example.org/value": [
                    {
                        "@id": "n2-o2-value"
                    }
                ]
            }
        ]
    }
]

Replace Travis with GitHub Actions

While there are are many reasons to move away from Travis, the most important one is that Travis has stopped notifying GitHub (see travis-ci/travis-ci#10204). Instead of fixing the Travis checks, I think it's better to just replace it altogether with GitHub Actions.

The rationale to use GitHub Actions is that we're dependent on GitHub for hosting of the source code anyway and GitHub Actions is considered by many (myself included) to be simpler, more feature-rich and more enjoyable than just about every existing alternative.

Proposed .NET version compatibility

We need to decide which versions of .NET we support going forward. I've stolen the matrix below from https://github.com/dotnet/standard/blob/master/docs/versions.md which aligns .NET versions with .NET Standard. I propose that given the nature of this library which should aim to support the lowest version of .NET standard across all the different platforms.

This implies that we would only actively support .NET Framework 4.6 or later. Very open to cries of protest and condemnation, but I think we should timebox this to 1 month for interested parties?

.NET Standard 1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0 2.1
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0 3.0
.NET Framework 4.5 4.5 4.5.1 4.6 4.6.1 4.6.11 4.6.11 4.6.11 N/A2
Mono 4.6 4.6 4.6 4.6 4.6 4.6 4.6 5.4 6.4
Xamarin.iOS 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.14 12.16
Xamarin.Mac 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.8 5.16
Xamarin.Android 7.0 7.0 7.0 7.0 7.0 7.0 7.0 8.0 10.0
Unity 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 2018.1 TBD
Universal Windows Platform 8.0 8.0 8.1 10.0 10.0 10.0.16299 10.0.16299 10.0.16299 TBD

Support for signing

Does this library support signing of JSON-LD documents? If it does, perhaps some instructions could be added to the repo, or if not supported, perhaps we could attempt to add this functionality?

Here is an example from the JSON-LD Playground where a document is signed with a Bitcoin private key:

image

Powershell build.ps1 script throws error logging an error

If an error occurs during the CoreCLR run, it tries to execute a cmd-let called "Error-Log" which, at least on my system, is not defined:


Error-Log : The term 'Error-Log' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\src\json-ld.net\build.ps1:61 char:5
+     Error-Log "Tests failed!!!"
+     ~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Error-Log:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Note that the .NET 4 version of the run doesn't use this cmdlet - instead it just uses Write-Host.

Am I doing something wrong or should I send a PR to use Write-Host for the CoreCLR portion too?

This is in reference to https://github.com/NuGet/json-ld.net/blob/master/build.ps1#L58

Tests are not checked into a Git repositories

I cloned the repo and wanted to check its tests to understand how it works. But although the solution file includes the test project, the project files are not pushed to the Git repo.

Solution does not build from 2017

The project does not build from VS2017 (appears to be hard-wired to 2015).
Attempting the upgrade process leaves errors:

Severity Code Description Project File Line Suppression State
Error The TargetFramework value 'net40-client' was not recognized. It may be misspelled. If not, then the TargetFrameworkIdentifier and/or TargetFrameworkVersion properties must be specified explicitly. json-ld.net C:\Program Files\dotnet\sdk\2.0.3\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.TargetFrameworkInference.targets 96
Error MSB3202 The project file "C:\src\json-ld.net\test\json-ld.net.tests\json-ld.net.tests.xproj" was not found. json-ld.net.tests C:\Users\andrew.gibson\AppData\Local\Temp\tmpa2e93ef2820d47cfbc8cf44fb5e8602f.proj 28
Error MSB4226 The imported project "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0\DotNet\Microsoft.DotNet.Props" was not found. Also, tried to find "DotNet\Microsoft.DotNet.Props" in the fallback search path(s) for $(VSToolsPath) - "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v15.0" . These search paths are defined in "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe.Config". Confirm that the path in the declaration is correct, and that the file exists on disk in one of the search paths. json-ld.net C:\src\json-ld.net\src\json-ld.net\json-ld.net.xproj 8

Are you open to this solution being ported to 2017?

Improve verification of DOM string IRI

This one is marked in the source code as "TODO" item, however I would like to emphasize its importance. Right now if I serialize and object into a JSON string and send it to JsonLdProcessor.Expand, it will mistakenly interpret it as a URI and of course fail. This is due to very weak check if in the code:

(input.Type == JTokenType.String && ((string)input).Contains(":"))

If it's a URI string that is expected would it be sufficient to match a regex here?

Stewardship of this repository

It has been discussed for a while now how this repository is being maintained, as exemplified by @goofballLogic in #24 (comment). The NuGet team seems to have run out of active maintainers and pull requests remain open for months and issues open for years without any attention.

A discussion on the public-linked-json mailing list brings forth different options for how the community can contribute to bring the stewardship of this repository back on track so the .NET community can have a well maintained and up to date JSON-LD implementation.

Here are some suggestions for how to move forward:

  • Set up a semi-automatic Sharpen-conversion from jsonld-java that will be repeated every now and then.
  • Add more maintainers to this repository.
  • Move the repository to a different organization.

We would love to get some input from @emgarten, @sblom or anyone else that have ownership status of this repository at the moment, because the current state of affairs is unfortunate.

Compaction algorithm doesn't compact properties with { "@type": "@id" } specified in context

Given

{
  "@context": {
    "@vocab": "http://test.com/",
    "stuff": { "@type": "@id" }
  }
}

when I compact the document:

{
   "http://test.com/stuff": { "@id": "some/stuff" }
}

I believe I should get:

{
  "stuff": "some/stuff"
}

This matches the playground output on the JSON-LD site: https://json-ld.org/playground/#/gist/c01a7b032f191afc9034c307caf17a61

The value compaction algorithm: (6.5.2 Algorithm, 4.1: https://json-ld.org/spec/latest/json-ld-api/#algorithm-8, retrieved 2018-01-10) says:

If number members is 1 and the type mapping of active property is set to @id, return the result of using the IRI compaction algorithm, passing active context, inverse context, and the value of the @id member for iri.

However, json-ld.net instead returns:

{
  "stuff": {
    "@id": "/some/stuff"
  }
}

Add LINQPad NuGet samples

Looks like we've resolved the long-standing "please provide usage examples" request by making the README much better, but I have been intending for ages to add LINQPad samples to the NuGet package so that a developer that wants to kick the tires can simply add the NuGet package to a LINQPad query and start playing around.

Any objections before I roll up my sleeves on that project?

Getting OutOfMemoryError while try to frame JsonLd

Getting OutOfMemoryError while try to frame JsonLd object using , please help me to resolve this issue

graphToFrame type is NQUARDS

 RDFDataset dataSet = RDFDatasetUtils.parseNQuads(graphToFrame);
JsonLdOptions options = new JsonLdOptions();
frameData = JsonUtils.fromString(frame);
Object rval = new JsonLdApi(options).fromRDF(dataSet);
Object framedJsonObject = JsonLdProcessor.frame(rval, frameData, options);

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.util.HashMap.newNode(Unknown Source)
at java.util.HashMap.putVal(Unknown Source)
at java.util.HashMap.put(Unknown Source)
at java.util.HashSet.add(Unknown Source)
at java.util.AbstractCollection.addAll(Unknown Source)
at java.util.HashSet.(Unknown Source)
at com.github.jsonldjava.core.JsonLdApi.removeDependents(JsonLdApi.java:1681)
at com.github.jsonldjava.core.JsonLdApi.removeEmbed(JsonLdApi.java:1676)
at com.github.jsonldjava.core.JsonLdApi.frame(JsonLdApi.java:1456)

@embed not supported?

@embed doesn't seem to be supported? I have created an example of the expected behavior in JSON-LD playground.

Expected output:

{
  "@context": {
    "ex": "https://ex#"
  },
  "@id": "https://a",
  "ex:createdBy": {
    "@id": "https://b",
    "ex:name": "Mads"
  },
  "ex:modifiedBy": {
    "@id": "https://b",
    "ex:name": "Mads"
  }
}

Actual output (name only embedded once):

{
  "@context": {
    "ex": "https://ex#"
  },
  "@id": "https://a",
  "ex:createdBy": {
    "@id": "https://b",
    "ex:name": "Mads"
  },
  "ex:modifiedBy": {
    "@id": "https://b"
  }
}

Reduce public API to a bare minimum

As part of discussion on #71 it was noted that we have a large public API including things which are not core to this library's purpose.

We should make as many parts of the library internal as possible while preserving the core public API which we intend to support in subsequent releases (even if this will change over time).

JsonLdProcessor.Frame(...): poor performance on large sets of objects

Version 1.0.4

From http://www.w3.org/TR/json-ld-api/#node-map-generation:

6.6.6.2) Otherwise, compare reference against every item in the array associated with the active property member of node. If there is no item equivalent to reference, append reference to the array. Two JSON objects are considered equal if they have equivalent key-value pairs.

This is implemented in json-ld.net as an n-squared algorithm, where n is the number of elements in the set. JsonLdProcessor.Frame(...) calls JsonLdApi.GenerateNodeMap(…), which for each element in an array calls JsonLdUtils.MergeValue(…), which in turn calls JsonLdUtils.DeepCompare(…) on the current set.

Stewardship of Nuget package

I have set up https://www.nuget.org/profiles/linked-data-dotnet as a (temporary?) organisation to host the Nuget package. To be secure it's best if at least 2 people have administrative oversight of this organisation (and are able to publish new versions etc.)

@asbjornu do you have a Nuget username and would you be willing to be added to the Nuget organisation and associated google group (email list)?

Support dependency-free API

The current API requires the use of Newtonsoft.Json in order to pass data into and out of the API. It would be good to provide a dependency-free core implementation (acting on either strings or simple objects), but also provide a drop-in version of the package which supports the existing Newtonsoft.Json signature.

No documentation

Well, it seems like a library that does something with JSON-LD but there is no documentation whatsoever. I install the NuGet package, put my using statement and then what?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.