Git Product home page Git Product logo

titanium-json-ld's Introduction

Titanium JSON-LD 1.1 Processor & API

An implementation of the JSON-LD 1.1 (JSON-based Serialization for Linked Data) specification in Java utilizing Jakarta JSON Processing.

The goals of Titanium are:

  • conformance to the specification
  • secure, stable, fast, A+ code (covered by ~1800 tests)
  • minimal external dependencies
    • only jakarta.json-api is required
  • simple to use

Java 11 CI Android (Java 8) CI CodeQL Codacy Badge Codacy Badge Maven Central License

Table of Contents

Conformance

The goal is to pass the official test suite and conform to the JSON-LD 1.1 specification.

Status

Feature Tests Pass Status Notes
Expansion 373 373 100%
Compaction 243 243 100%
Flattening 55 55 100%
JSON-LD to RDF 453 451 99.5%
RDF to JSON-LD 51 51 100%
Framing 89 88 98.8%
Remote Document and Context Retrieval 18 17 94.4%

See EARL results from the JSON-LD 1.1 Test Suite for more details.

CLI

LD-CLI is a native command line utility for Ubuntu, Mac, Windows

Extensions

Usage

Installation

Titanium

Maven

Java 11+

<dependency>
    <groupId>com.apicatalog</groupId>
    <artifactId>titanium-json-ld</artifactId>
    <version>1.4.0</version>
</dependency>
Gradle

Java 8+, Android API Level >=24

implementation("com.apicatalog:titanium-json-ld-jre8:1.4.0")

JSON-P Provider

Add JSON-P provider, if it is not on the classpath already.

Maven
<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.json</artifactId>
    <version>2.0.1</version>
</dependency>
Gradle
implementation("org.glassfish:jakarta.json:2.0.1")

Documentation

javadoc

Examples

Titanium provides high-level JsonLd API to interact with the processor.

Transformations

// Expansion
JsonLd.expand("https://w3c.github.io/json-ld-api/tests/expand/0001-in.jsonld")
      .ordered()
      .get();

JsonLd.expand("file:/home/filip/document.json")    // HTTP(S) and File schemes supported
      .context("file:/home/filip/context.jsonld")  // external context
      .get();

// Compaction
JsonLd.compact("https://example/expanded.jsonld", "https://example/context.jsonld")
      .compactToRelative(false)
      .get();

// Flattening
JsonLd.flatten("https://example/document.jsonld").get();

// JSON-LD to RDF
JsonLd.toRdf("https://example/document.jsonld").get();

// RDF to JSON-LD
JsonLd.fromRdf("https://example/document.nq").options(options).get();

// Framing
JsonLd.frame("https://example/document.jsonld", "https://example/frame.jsonld").get();

Local JSON Document

Document document = JsonDocument.of(InputStream) or JsonDocument.of(Reader) ...

JsonLd.expand(document).get();

JsonLd.compact(document, contextDocument).get();
...

Processing Timeout [experimental]

A processor gets terminated eventually after a specified time. Please note the duration does not cover DocumentLoader processing time. You have to set-up a read timeout separately.

// since 1.4.0
JsonLd.expand(...).timeout(duration)...get();

HTTP Document Loader Timeout

Configure and set a custom HTTP document loader instance.

// since 1.4.0 - set read timeout
static DocumentLoader LOADER = HttpLoader.defaultInstance().timeount(Duration.ofSeconds(30));
...
JsonLd.expand(...).loader(LOADER).get();

Document caching

Configure LRU-based cache for loading documents. The argument determines size of the LRU-cache.

// since 1.4.0
JsonLd.toRdf("https://example/document.jsonld").loader(new LRUDocumentCache(loader, capacity)).get();

You can share an instance of LRUDocumentCache among multiple calls to reuse cached documents.

// since 1.4.0
DocumentLoader cachedLoader = new LRUDocumentCache(loader, capacity);

JsonLd.toRdf("https://example/document.jsonld").loader(cachedLoader).get();
JsonLd.toRdf("https://example/another-document.jsonld").loader(cachedLoader).get();

Contributing

All PR's welcome!

  • develop
    • implement a new feature
    • fix an existing issue
    • improve an existing implementation
  • test
    • report a bug
    • implement a test case
  • document
    • write javadoc
    • write a tutorial
    • proofread an existing documentation
  • promote
    • star, share, the project
    • write an article
  • sponsor
    • your requests get top priority
    • you will get a badge

Building

Fork and clone the project repository.

Java 11

> cd titanium-json-ld
> mvn clean package

Java 8

> cd titanium-json-ld
> mvn -f pom_jre8.xml clean package

Resources

Commercial Support

Commercial support is available at [email protected]

titanium-json-ld's People

Contributors

bobeal avatar codacy-badger avatar dependabot[bot] avatar ebremer avatar filip26 avatar jmvanel avatar jtownson avatar kevinpeterson avatar lolgab avatar magemasher avatar simon-greatrix avatar skodapetr avatar umbreak 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

titanium-json-ld's Issues

triples with aliased @id and @base are missing at root level

Describe the bug
Two triples corresponding to @id "id" : "54141546" at root level in the JSON are lost.
Both @id 's are associated to a @base .
So there is just one triple left, corresponding to the inner JSON block :

<https://www.inaturalist.org/users/3295956>
  <http://xmlns.com/foaf/0.1/img> 
    <https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662>

(works fine with Distiller & JS-LD Playground)

To Reproduce
Prepare files

echo '{
  "uri" : "54141546" ,
  "description" : "Aucune fleur ou fruit, glauque",
  "user" : {
    "id" : "3295956",
    "icon" : "https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662"
  } }' > test-bug-OK.json
echo '{ "@context": {
  "foaf": "http://xmlns.com/foaf/0.1/",
  "rdfs" : "http://www.w3.org/2000/01/rdf-schema#" ,
  "@base" : "https://api.inaturalist.org/v1/observations/" ,  
  "uri": "@id",
  "description" : "rdfs:comment" ,
  "user" : {
     "@id": "foaf:maker",
     "@context": {
      "icon" : { "@id": "foaf:img", "@type": "@id" } ,
      "@base" : "https://www.inaturalist.org/users/" ,
      "id" : "@id"
    }
  }
} }' > test-bug.context-OK.jsonld

Java code

String dir = "file:////home/jmv/test/"
String uri = dir + "test-bug-OK.json";
String context = dir + "test-bug.context-OK.jsonld";
JsonLdOptions options = new JsonLdOptions();
options.setExpandContext(context);
System.println(  JsonLd.toRdf( uri ) . options(options) . get() )

Expected behavior
Like with Distiller:

<https://api.inaturalist.org/v1/observations/54141546> <http://xmlns.com/foaf/0.1/maker> <https://www.inaturalist.org/users/3295956> .
<https://api.inaturalist.org/v1/observations/54141546> <http://www.w3.org/2000/01/rdf-schema#comment> "Aucune fleur ou fruit, glauque" .
<https://www.inaturalist.org/users/3295956> <http://xmlns.com/foaf/0.1/img> <https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662> 

Additional context
NOTE : to be able to test I commented out the faulty Java code that prevents use of file: URL's , see preceding issue .

HttpLoader doesn't properly process missing content-type

Describe the bug
If received response doesn't have content-type then an exception is thrown

java.lang.IllegalArgumentException: The provided content type is null.
	at com.apicatalog.jsonld.document.DocumentParser.parse(DocumentParser.java:49)
	at com.apicatalog.jsonld.loader.HttpLoader.createDocument(HttpLoader.java:233)
	at com.apicatalog.jsonld.loader.HttpLoader.loadDocument(HttpLoader.java:193)
	at com.apicatalog.jsonld.loader.SchemeRouter.loadDocument(SchemeRouter.java:62)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:502)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:174)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.initLocalContext(ObjectExpansion.java:202)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:101)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
	at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:69)
	at com.apicatalog.jsonld.api.impl.ToRdfApi.get(ToRdfApi.java:179)
	at controllers.Json2RDFServiceApp.$anonfun$json2rdf$3(Json2RDFServiceApp.scala:58)
	at scala.util.Try$.apply(Try.scala:213)
	at controllers.Json2RDFServiceApp.$anonfun$json2rdf$1(Json2RDFServiceApp.scala:46)

To Reproduce
Use HttpLoader to load a resource with no content-type header.

Expected behavior
JsonLdError.DOCUMENT_LOADING_ERROR should be thrown.

Additional context
Consider fallback if content-type is missing.

Consideration on performance

This is just informative and for no means with any aim to criticise. I think the code is written very tidily and it is great to have an alternative to Json-LD Java.

I did some benchmarks comparing Json-LD Java with Titanium using the W3C compliance test suite (just the subset that Json-LD Java supported). Please take a look at the results.

I think it is normal performance in Json-LD Java is higher due to the lesser complexity of Json-LD 1.0 spec. Also due to their maturity they had the chance to improve performance. But I'm sure there is a room for performance improvement on this project too.

CLI support

Add an executable command allowing to perform JSON-LD transformations on a given input

e.g.

> cat input.json | jsonld.sh expand --context context.jsonld > expanded.jsonld

Parser fails quietly with an @id with no scheme

{
  "@id" : "x.y.z",
  "x:item" : {
    "@value" : "A_Token",
    "@type" : "http://www.w3.org/2001/XMLSchema#token"
  }
}

The above json-ld has an id with a relative (not absolute) URI.
The parser processes this as input without error but emits
no Triples output.
Code:

  try {
      JsonDocument doc = JsonDocument.of(stream);
      ToRdfApi tt = JsonLd.toRdf(doc);
      RdfDataset rdf = tt.get();   
      List<RdfNQuad> list = rdf.toList();
      ....
    } catch (JsonLdError e) {
    ....
    }

The list is empty.

I believe that the parser should either:

  • process the id as-is
  • signal an error in the input format.

NOTE: Change the @id to 'urn:x.y.z' and it works fine.

No setting to Skolemize blank nodes

Describe the bug
Unable to find setting to Skolemize blank nodes as RDF4J parser allows.

To Reproduce
Steps to reproduce the behavior:
This is my input json-ld

 {
   "@context": {
     "@version": 1.1,
     "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
     "xsd": "http://www.w3.org/2001/XMLSchema#",
     "et": "urn:acme:com#",
     "@vocab": "urn:acme:com#",
     "aId": {
       "@id": "@id",
       "@type": "@id"
     },
     "aVId": {
       "@id": "et:aVId",
       "@type": "@id"
     },
     "parts": {
       "@id": "et:parts",
       "@container": "@list",
       "@context": {
         "id": {
           "@id": "@id"
         }
       }
     },
     "id": {
       "@id": "et:id",
       "@type": "xsd:string"
     },
     "title": {
       "@id": "et:title",
       "@language": "en"
     },
     "type": {
       "@id": "et:type",
       "@type": "@vocab"
     },
     "version": {
       "@id": "et:version",
       "@type": "@id"
     }
   },
 
   "type": "Book",
   "title": "Title1",
   "parts": [
     {
       "version": "urn:acme:com:1111",
       "id": "urn:acme:com:2222",
       "type": "chapter",
       "title": "Chapter1"
     }
   ],
   "aId": "urn:acme:com:3333",
   "aVId": "urn:acme:com:4444"
 }

This is the set of triples that gets generated

 <urn:acme:com:2222> <urn:acme:com#title> "Chapter1"@en .
 <urn:acme:com:2222> <urn:acme:com#type> <urn:acme:com#chapter> .
 <urn:acme:com:2222> <urn:acme:com#version> <urn:acme:com:1111> .
 <urn:acme:com:3333> <urn:acme:com#aVId> <urn:acme:com:4444> .
 <urn:acme:com:3333> <urn:acme:com#parts> _:genid5f5f3ab0 .
 _:genid5f5f3ab0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> <urn:acme:com:2222> .
 _:genid5f5f3ab0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> <http://www.w3.org/1999/02/22-rdf-syntax-ns#nil> .
 <urn:acme:com:3333> <urn:acme:com#title> "Title1"@en .
 <urn:acme:com:3333> <urn:acme:com#type> <urn:acme:com#Book> .

I cannot find a setting to Skolemize the blank nodes. I want to be able to create RDF4J statements to add these to remote repository using RDF4J Model api and without it I am not able to do so

Expected behavior
There should be an option similar to RDF4J Skolemize
https://rdf4j.org/javadoc/latest/org/eclipse/rdf4j/rio/helpers/BasicParserSettings.html#SKOLEMIZE_ORIGIN

Additional context
Add any other context about the problem here.

INVALID_IRI_MAPPING when using specific context in form of an array

When trying to process a JSON-LD 1.1 file using Titanium (e.g. compact, but also other operations), I get the INVALID_IRI_MAPPING exception. The file processed is:

{
    "@context": [
        "https://pod-test.mvcr.gov.cz/otevřené-formální-normy/pracovní-místa/draft/kontexty/pracovní-místo.jsonld",
        {
            "@version": 1.1,
            "@import": "https://ofn.gov.cz/věc/2020-07-01/kontexty/věc.jsonld",
            "@propagate": true,
            "nedefinováno": "https://slovník.gov.cz/nedefinováno/",
            "místa": "https://slovník.gov.cz/generický/pracovní-místa/pojem/",
            "Pracovní místo ve vědě a výzkumu": {
                "@id": "nedefinováno:pracovní-místo-ve-vědě-a-výzkumu",
                "@context": {
                    "pracoviště": {
                        "@id": "místa:má-pracoviště",
                        "@context": "https://pod-test.mvcr.gov.cz/otevřené-formální-normy/věda-a-výzkum/draft/kontexty/věda-a-výzkum.jsonld"
                    }
                }
            }
        }
    ],
    "typ": [
        "Pracovní místo ve vědě a výzkumu"
    ],
    "iri": "https://data.mff.cuni.cz/zdroj/pracovní-místa-mff-uk/202008-AP1-KSI",
    "pracoviště": {
        "typ": "Pracoviště",
        "iri": "https://data.mff.cuni.cz/zdroj/číselník/organizační-struktura/oddělení/204"
    }
}

The weird thing is that when I leave only one of the two items in the @context array, the processing does not fail. It only fails when there are both items.

The exception:

Caused by: com.apicatalog.jsonld.JsonLdError: There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED].
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:572)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:173)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.initPropertyContext(ObjectExpansion.java:148)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:99)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:905)
	at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120)
	at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
	at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
	at com.apicatalog.jsonld.api.ExpansionApi.get(ExpansionApi.java:142)
	at com.linkedpipes.plugin.transformer.jsonldformattitanium.TitaniumOperator.expand(TitaniumOperator.java:91)
	... 6 common frames omitted
Caused by: com.apicatalog.jsonld.JsonLdError: The local context defined within a term definition is invalid [code=INVALID_SCOPED_CONTEXT].
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:534)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:451)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:565)
	... 16 common frames omitted
Caused by: com.apicatalog.jsonld.JsonLdError: A local context contains a term that has an invalid or missing IRI mapping [code=INVALID_IRI_MAPPING].
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:358)
	at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:451)
	at com.apicatalog.jsonld.context.TermDefinitionBuilder.create(TermDefinitionBuilder.java:531)
	... 18 common frames omitted

Note that the referenced external contexts re-use each other, which even forms a cycle, but that should not be an issue, as it holds even when one of the two items in the @context array stays.

Blank nodes output as IRI in fromRdf

Describe the bug
After building a single triple RdfDataset from API , and giving it to fromRdf, the blank node "bn1" is output as an IRI :
[{"@id":"urn:s1","urn:p1":[{"@id":"bn1"}]}]

To Reproduce
This is Scala. I can provide a Java code, but I think you can manage that :) .

import com.apicatalog.rdf.impl.DefaultRdfProvider
import com.apicatalog.jsonld.api.impl.FromRdfApi
import com.apicatalog.jsonld.JsonLd
import com.apicatalog.jsonld.document.RdfDocument
import com.apicatalog.rdf.RdfDataset
import javax.json.JsonArray
import java.io.StringWriter
import javax.json.Json

object TestTitaniumBlankNodes extends App {
  val rdfProvider = DefaultRdfProvider.INSTANCE
  val subject = rdfProvider.createIRI("urn:s1")
  val objet = rdfProvider.createBlankNode("bn1")
  val predicate = rdfProvider.createIRI("urn:p1")
  val titaniumDS: RdfDataset = rdfProvider.createDataset()
  val nquad = rdfProvider.createNQuad(subject, predicate, objet, null)
  titaniumDS.add(nquad)

  val fromRdf: FromRdfApi =
      JsonLd.fromRdf(
        RdfDocument.of(titaniumDS) )

  printJsonArray(fromRdf . get) // KO: blank node as IRI !!!!!!!!!!!!!!!!!!!!

  def printJsonArray(jsa: JsonArray) {
    val sw = new StringWriter()
    val jsonWriter = Json.createWriter(sw)
    jsonWriter.writeArray(jsa)
    jsonWriter.close()
    sw.close()
    println(sw.toString())
  }
}

Expected behavior
Real blank node:

[{
"@id":"urn:s1",
"urn:p1": "_:bn1" }]`

Additional context
Distilled from issue #89

Two @base => JsonValueImpl cannot be cast to class javax.json.JsonStructure

Describe the bug
A @base in @context , and another @base in data block entails a ClassCastException: class javax.json.JsonValueImpl cannot be cast to class javax.json.JsonStructure (javax.json.JsonValueImpl and javax.json.JsonStructure .

To Reproduce
Call
JsonLd.toRdf(JsonDocument . of (is)). get()
where InputStream is reads:

{
  "@context": {
    "@base" : "https://beta.grottocenter.org/api/v1/entrances/"
  } ,
  "@base": "b",
  "@id": "4",
  "urn:name": "Prérouge (Grotte de)"
}

Expected behavior
No exception, of course.
https://json-ld.org/playground/ does not take in account the @base in data block .
Removing it removes the exception.

Additional context
Using latest Titanium 0.8.6 .
The stack is

java.lang.ClassCastException: class javax.json.JsonValueImpl cannot be cast to class javax.json.JsonStructure 
	at com.apicatalog.jsonld.flattening.NodeMapBuilder.build(NodeMapBuilder.java:389)
	at com.apicatalog.jsonld.flattening.NodeMapBuilder.build(NodeMapBuilder.java:122)
	at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:73)

JsonLd.toRdf takes a long time for a specific example

Describe the bug
I think there may be a performance issue when contexts recurse. I have a small example that does complete, but takes several minutes.

To Reproduce
See the JSONLD content to reproduce is here: https://tinyurl.com/y4jlpkz5

I plug that into JsonLd.toRdf as such:

ToRdfApi rdf = JsonLd.toRdf(stream).options(jsonLdOptions);
RdfDataset dataset = rdf.get();

Expected behavior
I would expect a small example like this to be fairly fast. I suspect there is some looping or something that can be optimized.

Cycling JSON->RDF->JSON: dropped data

JSON-RDF-JSON issue

In trying to do the json->rdf->json cycle, the
last entry of the outer list : [7,-7] is lost converting
RDF->JSON

input data:

{
"https://purl.org/geojson/vocab#coordinates": [{
"@list": [
{"@list": [{"@value": 10.0}, {"@value": -10.0}]},
{"@list": [{"@value": 9.0}, {"@value": -9.0}]},
{"@list": [{"@value": 8.0}, {"@value": -8.0}]},
{"@list": [{"@value": 7.0}, {"@value": -7.0}]}
]
}]
}

code:

	String input = 
	"{\n" + 
	"  \"https://purl.org/geojson/vocab#coordinates\": [{\n" + 
	"    \"@list\": [\n" + 
	"      {\"@list\": [{\"@value\": 10.0}, {\"@value\": -10.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 9.0}, {\"@value\": -9.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 8.0}, {\"@value\": -8.0}]},\n" + 
	"      {\"@list\": [{\"@value\": 7.0}, {\"@value\": -7.0}]}\n" + 
	"    ]\n" + 
	"  }]\n" + 
	" }\n" + 
	"";
	
	ByteArrayInputStream stream = new ByteArrayInputStream(input.getBytes());

	JsonDocument doc = JsonDocument.of(stream);
	ToRdfApi tt = JsonLd.toRdf(doc);
	RdfDataset rdf = tt.get();
	
	Document rdfDoc = RdfDocument.of(rdf);
	
	FromRdfApi fromRdf = JsonLd.fromRdf(rdfDoc);
	JsonArray array = fromRdf.get();
	System.out.println(array);

JsonLdOptions @base overrides activeContext @base

Input Json: https://w3c.github.io/json-ld-api/tests/compact/0047-in.jsonld
Input context: https://w3c.github.io/json-ld-api/tests/compact/0047-in.jsonld

JsonLdTestCaseOptions options = new JsonLdTestCaseOptions();
options.setBase(URI.create("http://fake.com/"))
JsonLd.compact(input,context).options(options).get();

should still return the expected output https://w3c.github.io/json-ld-api/tests/compact/0047-out.jsonld
since the active @context @base value should override the JsonLDOptions @base

Superfluous arrays in Json -> JsonLD expansion

Arrays around single value objects are unnecessary and make reading the expansion result and further processing more awkward:
For example:

[{
  "http://acme.org/feature/structure_comment": [{
    "@value": "A comment"
  }],
  "http://acme.org/feature/structure_type": [{
    "@value": "a bolt"
  }],
  "http://acme.org/feature/load_measurement": [{
    "@value": 45
  }],
  "http://acme.org/feature/structure_id": [{
    "@value": "a.b.111"
  }]
}]

could be validly written as:

{
  "http://acme.org/feature/structure_comment": {
    "@value": "A comment"
  },
  "http://acme.org/feature/structure_type": {
    "@value": "a bolt"
  },
  "http://acme.org/feature/load_measurement": {
    "@value": 45
  },
  "http://acme.org/feature/structure_id": {
    "@value": "a.b.111"
  }
}

I also believe that the use of @value in this example is superfluous, but is less annoying to the eye.

add Maven wrapper

add mvnw and mvnw.cmd commands to the root directory to allow building the project without having Maven installed.

Context Builder API

Is your feature request related to a problem? Please describe.
Sometimes a combination of contexts is needed. e.g. a combination of local and remote context.

Describe the solution you'd like
Provide API, a builder, allowing to create combined context.

e.g.

JsonLd.createContext().add(localcontext).add(remotecontext).build()

Describe alternatives you've considered
Now, a user must create a context manually or with JSON-P.

Question: disabling remote context loading

While it is clearly part of the JSON-LD specification to fetch remote context documents (either via "@context": "https://example.com/context.json" or via @import within an existing @context), is there a mechanism for disabling this feature? It seems that JsonLdOptions.setDocumentLoader(null) may work for that.

The use case I have in mind is an LDP server that accepts JSON-LD documents but which (for security reasons) does not wish to fetch arbitrary remote resources.

Nested @embed directive affects processing at a higher level

Describe the bug

When I create a frame with a nested @embed directive, it seems to affect the frame processing at a higher level, which differs from the behavior of the framing processor at the JSON-LD Playground.

To Reproduce

Take for example the following graph:

{
  "@graph": [
    {
      "@id": "http://n2t.net/ark:/39333/ncg/dataset",
      "@type": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag",
      "member": [
        "http://n2t.net/ark:/39333/ncg/place/NCG11248",
        "http://n2t.net/ark:/39333/ncg/place/NCG07554",
        "http://n2t.net/ark:/39333/ncg/place/NCG03755"
      ]
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG03755",
      "@type": "http://n2t.net/ark:/39333/ncg/type#Mountain",
      "county": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "label": "Crawford Mountain"
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG07554",
      "@type": "http://n2t.net/ark:/39333/ncg/type#Community",
      "county": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "label": "Ichley"
    },
    {
      "@id": "http://n2t.net/ark:/39333/ncg/place/NCG11248",
      "@type": "http://n2t.net/ark:/39333/ncg/type#County",
      "label": "Orange County",
      "description": "Not to be confused with Orange County, CA"
    }
  ],
  "@context": {
    "label": {
      "@id": "http://www.w3.org/2004/02/skos/core#label"
    },
    "description": {
      "@id": "http://www.w3.org/2004/02/skos/core#note"
    },
    "county": {
      "@id": "http://n2t.net/ark:/39333/ncg/vocab#county",
      "@type": "@id"
    },
    "member": {
      "@id": "http://www.w3.org/2000/01/rdf-schema#member",
      "@type": "@id"
    }
  }
}

And this frame:

{
  "@context": {
    "@base": "http://n2t.net/ark:/39333/ncg/place/",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
    "nct": "http://n2t.net/ark:/39333/ncg/type#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "records": {
      "@container": "@set",
      "@type": "@id",
      "@id": "rdfs:member"
    },
    "county": {
      "@container": "@set",
      "@type": "@id",
      "@id": "ncv:county"
    }
  },
  "@type": "rdf:Bag",
  "records": {
    "@id": {},
    "county": {
      "@embed": "@always",
      "@explicit": true,
      "skos:label": {}
    }
  }
}

(See the above on the playground).

Expected behavior

On the JSON-LD Playground, the above graph and frame produce these results, which are what I would expect: county nodes are always embedded and respecting the @explicit directive, but this does not affect the records level.

{
  "@context": {
    "@base": "http://n2t.net/ark:/39333/ncg/place/",
    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
    "nct": "http://n2t.net/ark:/39333/ncg/type#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "records": {
      "@container": "@set",
      "@type": "@id",
      "@id": "rdfs:member"
    },
    "county": {
      "@container": "@set",
      "@type": "@id",
      "@id": "ncv:county"
    }
  },
  "@id": "../dataset",
  "@type": "rdf:Bag",
  "records": [
    {
      "@id": "NCG11248",
      "@type": "nct:County",
      "county": [],
      "skos:label": "Orange County",
      "skos:note": "Not to be confused with Orange County, CA"
    },
    {
      "@id": "NCG07554",
      "@type": "nct:Community",
      "county": [
        {
          "@id": "NCG11248",
          "@type": "nct:County",
          "skos:label": "Orange County"
        }
      ],
      "skos:label": "Ichley"
    },
    {
      "@id": "NCG03755",
      "@type": "nct:Mountain",
      "county": [
        {
          "@id": "NCG11248",
          "@type": "nct:County",
          "skos:label": "Orange County"
        }
      ],
      "skos:label": "Crawford Mountain"
    }
  ]
}

However, using Titanium I get the following results:

{
    "@id": "../dataset",
    "@type": "rdf:Bag",
    "records": [
        {
            "@id": "NCG03755",
            "@type": "nct:Mountain",
            "county": [
                {
                    "@id": "NCG11248",
                    "@type": "nct:County",
                    "skos:label": "Orange County"
                }
            ],
            "skos:label": "Crawford Mountain"
        },
        {
            "@id": "NCG07554",
            "@type": "nct:Community",
            "county": [
                {
                    "@id": "NCG11248",
                    "@type": "nct:County",
                    "skos:label": "Orange County"
                }
            ],
            "skos:label": "Ichley"
        },
        "NCG11248"
    ],
    "@context": {
        "@base": "http://n2t.net/ark:/39333/ncg/place/",
        "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
        "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
        "ncv": "http://n2t.net/ark:/39333/ncg/vocab#",
        "nct": "http://n2t.net/ark:/39333/ncg/type#",
        "skos": "http://www.w3.org/2004/02/skos/core#",
        "records": {
            "@container": "@set",
            "@type": "@id",
            "@id": "rdfs:member"
        },
        "county": {
            "@container": "@set",
            "@type": "@id",
            "@id": "ncv:county"
        }
    }
}

Note that the node for Orange County at the records level is just an @id reference.

Additional context

It seems to me that what is happening is that the records level is being processed with the default "@embed": "@once" directive, but that the embeddings at the county level are being counted as fulfilling that one embedding, so that at the records level Orange County is never embedded.

file: URL's are not accepted for context location

To be able to run Titanium with local files , I had to comment out some code :

git diff *
diff --git a/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java b/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
index edb041c..2a287ca 100644
--- a/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
+++ b/src/main/java/com/apicatalog/jsonld/api/impl/ExpansionApi.java
@@ -71,9 +71,9 @@ public final class ExpansionApi implements CommonApi<ExpansionApi>, LoaderApi<Ex
     public ExpansionApi context(String contextLocation) {
         
         if (contextLocation != null) {
-            if (!UriUtils.isNotURI(contextLocation)) {
-                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
-            }
+//            if (!UriUtils.isNotURI(contextLocation)) {
+//                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
+//            }
             options.setExpandContext(UriUtils.create(contextLocation));
             
         } else {
diff --git a/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java b/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
index ada138d..a737db2 100644
--- a/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
+++ b/src/main/java/com/apicatalog/jsonld/api/impl/ToRdfApi.java
@@ -72,9 +72,9 @@ public final class ToRdfApi implements CommonApi<ToRdfApi>, LoaderApi<ToRdfApi>,
     public ToRdfApi context(String contextLocation) {
         
         if (contextLocation != null) {
-            if (!UriUtils.isNotURI(contextLocation)) {
-                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
-            }
+//            if (!UriUtils.isNotURI(contextLocation)) {
+//                throw new IllegalArgumentException("Context location must be valid URI or null but is [" + contextLocation + ".");
+//            }
             options.setExpandContext(UriUtils.create(contextLocation));
             
         } else {

And now this can run :

JsonLd.toRdf( uri ) . context( context ).get

The @base attribute is only used if the remote contexts list is empty.

Describe the bug

The @base attribute is only used if the remote contexts list is empty.

To Reproduce

Populate the @base attribute along with one or more entries in the remote contexts.

For example, I would expect this to result in one triple when going to RDF:

{
  "@id": "1",
  "test": "some-test",
  "@context": [
    "https://fhircat.org/fhir-r5/original/contexts/careplan.context.jsonld",
    {
      "nodeRole": {
        "@type": "@id",
        "@id": "fhir:nodeRole"
      },
      "@base": "http://hl7.org/fhir/",
      "owl:imports": {
        "@type": "@id"
      },
      "owl:versionIRI": {
        "@type": "@id"
      }
    }
  ]
}

Expected behavior

I believe the correct interpretation of this spec is that @base should be considered if the context is not a remote context (not necessarily if the remote contexts list is empty). See linked issue below.

Additional context

w3c/json-ld-api#505

HttpLoader: Suppress HTTP Content-Type validation

Feature request is related to a problem

I'm frustrated when a JSON-LD source has a linked @context whose MIME type is not one of the JSON expected types.
In this case it is a raw github URL, that says test/plain .
This, or a file, is very convenient to develop and debug a new @context .
Moreover, being explicitly loaded as a @context , is is supposed to be application/ld+json .
I deserves a warning for sure, but not a blocking exception.

scala> JsonLd.toRdf("https://geb.ffspeleo.fr/api/api/v2/").get()
com.apicatalog.jsonld.JsonLdError: There was a problem encountered loading a remote context [code=LOADING_REMOTE_CONTEXT_FAILED].
  at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:523)
  at com.apicatalog.jsonld.context.ActiveContextBuilder.create(ActiveContextBuilder.java:173)
  at com.apicatalog.jsonld.expansion.ObjectExpansion.initLocalContext(ObjectExpansion.java:202)
  at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:101)
  at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:116)
  at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:124)
  at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:69)
  at com.apicatalog.jsonld.processor.ToRdfProcessor.toRdf(ToRdfProcessor.java:58)
  at com.apicatalog.jsonld.api.ToRdfApi.get(ToRdfApi.java:175)
  ... 31 elided
Caused by: com.apicatalog.jsonld.JsonLdError: Unsupported media type 'text/plain'. Supported content types are [application/ld+json, application/json, +json, application/n-quads]
  at com.apicatalog.jsonld.document.DocumentParser.fireUnsupportedMediaType(DocumentParser.java:99)
  at com.apicatalog.jsonld.document.DocumentParser.parse(DocumentParser.java:60)
  at com.apicatalog.jsonld.loader.HttpLoader.createDocument(HttpLoader.java:242)
  at com.apicatalog.jsonld.loader.HttpLoader.loadDocument(HttpLoader.java:202)
  at com.apicatalog.jsonld.loader.SchemeRouter.loadDocument(SchemeRouter.java:62)
  at com.apicatalog.jsonld.context.ActiveContextBuilder.fetch(ActiveContextBuilder.java:519)
  ... 39 more

Other JSON-LD engines

JENA (with jsonld-java) processes such JSON-LD source well :
$JENA/bin/riot --output=turtle --syntax=jsonld https://geb.ffspeleo.fr/api/api/v2/
The Playground also accepts such input:

{
  "@context": "https://raw.githubusercontent.com/jmvanel/Karstlink-ontology/master/geb.ffspeleo.fr_context.jsonld",
  "@graph": [
    {
      "@id": "321",
      "@type": "UndergroundCavity",
      "name": "Biefs Bousset",
      "latitude": "46.99406",
      "longitude": "6.07472",
      "altitude": "770",
      "locates": [
        {
          "@id": "628",
          "@type": "geo:Point",
          "label": "station_321-590",
          "dwc:Occurrence": [
            {
              "@id": "4278",
              "@type": "dwc:Occurrence",
              "event date": "2010-03-07",
              "associated taxa": "Amilenus aurantiacus",
              "dwci:toTaxon": "http://taxref.mnhn.fr/lod/taxon/337326/13.0"
            }
            ]
        }
      ]
    }
  ]  
}

Use native types generate an invalid json ld

Describe the bug
Setting use native types to true return an invalid json ld: all string literals are converted to a value with xsd:string attached.

To Reproduce

Steps to reproduce the behavior:

JsonLdOptions  jlo = new JsonLdOptions();
jlo.setUseNativeTypes(true);
JsonArray rdf = JsonLd.fromRdf(RdfDocument.of(streamResult)).options(jlo).get();

The variable streamResult contains the example 1 of rdf nq

<http://one.example/subject1> <http://one.example/predicate1> <http://one.example/object1> <http://example.org/graph3> .
_:subject1 <http://an.example/predicate1> "object1" <http://example.org/graph1> .
_:subject2 <http://an.example/predicate2> 1^^<http://www.w3.org/2001/XMLSchema#integer> <http://example.org/graph5> .

The obtained result is
[{"@id":"http://example.org/graph1","@graph":[{"@id":"_:subject1","http://an.example/predicate1":[{"@value":"object1^^http://www.w3.org/2001/XMLSchema#string"}]}]},{"@id":"http://example.org/graph3","@graph":[{"@id":"http://one.example/subject1","http://one.example/predicate1":[{"@id":"http://one.example/object1"}]}]},{"@id":"http://example.org/graph5","@graph":[{"@id":"_:subject2","http://an.example/predicate2":[{"@value":1}]}]}]

"@value":"object1^^http://www.w3.org/2001/XMLSchema#string" is an invalid format, the correct value would be
{"@value":"object1"} or {"@value":"object1","@type":"http://www.w3.org/2001/XMLSchema#string"}.

Expected behavior
Using useNativeTypes I would expect the object1 that is a string to become a simple {"@value":"object1"} without the type.
With the current example full result:
[{"@id":"http://example.org/graph1","@graph":[{"@id":"_:subject1","http://an.example/predicate1":[{"@value":"object1"}]}]},{"@id":"http://example.org/graph3","@graph":[{"@id":"http://one.example/subject1","http://one.example/predicate1":[{"@id":"http://one.example/object1"}]}]},{"@id":"http://example.org/graph5","@graph":[{"@id":"_:subject2","http://an.example/predicate2":[{"@value":1}]}]}]

Java 11 api usage prevents titanium being used on android and with Scala

Problem faced using on android
Calls such as com.apicatalog.jsonld.JsonLd.toRdf(...) instantiate a default DocumentLoader which has a dependency on Java 11's java.net.http.HttpClient. If the calling code tries to set options such as JsonLd.toRdf(...).loader(jdk8CompatibleLoader) this fails to circumvent the loading of Java 11 classes (because the default java 11 DocumentLoader instance is created eagerly).

Problem faced using from Scala
Scala projects still commonly use Java 8 as the runtime. The problem above thus causes incompatible class version errors.

Describe the solution you'd like
I recommend you refactor the code so that the core API is compatible with Java 8. For android, it would work if any concrete, default implementations which depend on Java 11 classes are not loaded in the case where the user provides overriding options. For Scala, I think you would have to actually compile under Java 8 (which would require reworking classes such as 'com.apicatalog.jsonld.loader.HttpLoader').

integer JSON value should be used for @id

Is feature request related to a problem?
Integer id's are very common in JSON API's. Alas it is explicitly forbidden by JSON-LD, for bad reasons.

Describe the proposed solution

{ "@context": {
  "id": "@id",
  "dwciri": "http://rs.tdwg.org/dwc/iri/",
  "taxonKey":{
    "@context": {
      "@base" : "https://api.gbif.org/v1/species/"
    },
    "@id": "dwciri:toTaxon", "@type": "@id"
  }
},
"id": 123 ,
"taxonKey": 7310533
}

Expected:

<https://json-ld.org/playground/123> <http://rs.tdwg.org/dwc/iri/toTaxon>
  <https://api.gbif.org/v1/species/7310533> .

This is what is obtained in Playground when changing 123 and 7310533 to strings.
@filip26 suggested that "Titanium could support that as an extension. e,g, JsonLdOptions.allowNumericId(boolean). " .
It could be the default, but that is debatable...

Describe alternatives considered
There is no alternative , except pre-processing the JSON, or post-processing with SPARQL.

Additional context
This issue on W3C has got some following:
w3c/json-ld-api#509
See previous issue with example:
json-ld/json-ld.org#742

Jena interop

It would be great to implement some conversion from the RdfDatasets of Jena and the ones from this library.

I know this should be implemented in another repo, so this library does not directly depend on Jena.

For your information, I've submitted an issue on the Jena side, and that's their response: https://issues.apache.org/jira/browse/JENA-1948

Consider to return Optional instead of null

see:

public static JsonValue getValue(JsonValue value) {
return isValueObject(value)
? value.asJsonObject().get(Keywords.VALUE)
: null;
}

public static JsonValue getValue(JsonValue value) {
return JsonUtils.isObject(value) ? value.asJsonObject().get(Keywords.DEFAULT) : null;
}

More meaningful error messages

Except for simple pure JSON syntax errors, there are no meaningful error messages; in many cases all we get is a JsonLdError exception and a stack.

Exemple:
JsonLd.expand( inatdir + "test-jmv.json").context(inatdir + "test.context.jsonld").get com.apicatalog.jsonld.api.JsonLdError at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:170) at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:123) at com.apicatalog.jsonld.expansion.ArrayExpansion.expand(ArrayExpansion.java:101) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:114) at com.apicatalog.jsonld.expansion.ObjectExpansion1314.expand(ObjectExpansion1314.java:339) at com.apicatalog.jsonld.expansion.ObjectExpansion.expand(ObjectExpansion.java:120) at com.apicatalog.jsonld.expansion.Expansion.compute(Expansion.java:123) at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:140) at com.apicatalog.jsonld.processor.ExpansionProcessor.expand(ExpansionProcessor.java:62) at com.apicatalog.jsonld.api.impl.ExpansionApi.get(ExpansionApi.java:148) ... 36 elided

The JSON data : test-jmv.json

{ "results" : [ {
         "id" : "54141546",
         "place_ids" : [ 97391, 108692 ],
         "map_scale" : null,
         "tags" : [],
         "captive" : false,
         "identifications_some_agree" : false,
         "geoprivacy" : null,
         "uri" : "https://www.inaturalist.org/observations/54141546",
         "quality_grade" : "needs_id",
         "taxon" : null,
         "site_id" : 1,
         "reviewed_by" : [],
         "description" : "Aucune fleur ou fruit, glauque, très drageonnant, pas plus de 40 cm, dans une prairie sèche rarement fauchée",
         "user" : {
            "id" : 3295956,
            "name" : "Jean-Marc Vanel",
            "icon" : "https://static.inaturalist.org/attachments/users/icons/3295956/thumb.jpg?1594113662"
         },
         "created_at" : "2020-07-24T12:03:34+02:00",
  "total_results" : 1,
   "per_page" : 1
} ] }

The context: test.context.jsonld

{
"@context": {
  "results" : "@graph" ,
  "id": "@id",
  "uri": "@id"
} }

The URL prefix:

String inatdir = "file:///home/jmv/src/rdf-convert/inaturalist.org/" ;

NOTE: removing in context the line "id": "@id", removes the error .

host Android build on maven central

Is your feature request related to a problem? Please describe.
Java 8/Android compatibility was added with #133, but presently I can't see the jar being hosted anywhere.

I was hoping to raise a PR on https://github.com/decentralized-identity/jsonld-common-java and https://github.com/decentralized-identity/did-common-java to provide Android support and titanium-json-ld is the key transitive dependency.

Describe the solution you'd like
titanium-json-ld uploaded under a separate artifactId to maven central or equivalent.

Describe alternatives you've considered
I've currently used git submodules to achieve the above, but it comes with problems:

  • gradle doesn't have a proxy for maven profiles, so building the maven module from gradle requires a fiddly bit of groovy
  • not sure if individual commits relate 1-1 to maven releases
  • it's ugly

I had a look in your github actions to try and raise a PR, but it didn't seem like the maven-push action actually does a maven push and I assumed you do it manually - I could well be misunderstanding though!

Additional context
Thanks for your work so far!

java.io.IOException: Too many open files in system when running tests

Hello,

I'm getting the following error when running the tests:

java.lang.InternalError: java.io.IOException: Too many open files in system
	at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:311)
	at java.net.http/jdk.internal.net.http.HttpClientImpl.create(HttpClientImpl.java:253)
	at java.net.http/jdk.internal.net.http.HttpClientBuilderImpl.build(HttpClientBuilderImpl.java:135)
	at com.apicatalog.jsonld.loader.HttpLoader.<init>(HttpLoader.java:38)
	at com.apicatalog.jsonld.api.JsonLdOptions.<init>(JsonLdOptions.java:88)
	at com.apicatalog.jsonld.suite.JsonLdTestCase.getOptions(JsonLdTestCase.java:154)
	at com.apicatalog.jsonld.JsonLdToRdfTest.testToRdf(JsonLdToRdfTest.java:62)
       .....

I believe com.apicatalog.jsonld.loader.HttpLoader is building a new java.net.http.HttpClient for each instance -- is that necessary, or can one instance of the HttpClient be reused?

export plain GeoJSON from GeoJSON-LD: issues RDF lists + key should be unprefixed

With JsonLd.toRdf() and an expandContext, plus my code to convert Titanium Dataset to Jena Dataset,
I was able to get RDF from a plain JSON .
( FYI see code https://github.com/jmvanel/semantic_forms/blob/master/scala/forms_play/app/controllers/Json2RDFServiceApp.scala#L43 )

Now I have the converse requirement. I want to export GeoJSON (being both plain GeoJSON & JSON-LD) from URI's having geographic data in a Jena TDB database.
See code
https://github.com/jmvanel/semantic_forms/blob/master/scala/geo/src/main/scala/jmvanel/GeoJSONexport.scala#L116
The issue is that I get mostly plain JSON with an @context :

    {
      "id": "http://semantic-forms.cc:1952/ldp/1511781044277-27461991065971051",
      "type": "Feature",
      "geometry": {
        "id": "406d4e19-bffb-4a8d-ba3e-2e9e7fadba17",
        "type": "Point",
        "geojson:coordinates": {
          "id": "c8d09a13-8359-49b5-819f-d76cce691faf",
          "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": "4.8193165",
          "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": {
            "id": "0194e207-ce2d-4377-9b33-1f397aa773cf",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#first": "45.9361934",
            "http://www.w3.org/1999/02/22-rdf-syntax-ns#rest": {
              "@list": []
            }
          }
        }
      },
      "properties": {

But there 2 issues:

  1. "geojson:coordinates" instead of "coordinates" ; but maybe the original context from https://geojson.org/geojson-ld/ is wrong here
  2. RDF lists are not output as JSON arrays

cf GeoJSON-LD example https://geojson.org/geojson-ld/
This example works fine with the JSON-LD distiller
http://rdf.greggkellogg.net/distiller?command=compact&format=jsonld&output_format=jsonld&useNativeTypes
that is, the JSON-LD processor outputs is a plain JSON with an @context , and "coordinates" key is correct, and JSON array is present .

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.