3

I need to take a large JSON-LD file as input for an algorithm that I am writing in Java. Therefore, I intend to use JSONLD-JAVA for that.

The JSONLD-JAVA page shows an example for reading a JSON-LD file, but not for navigating or traversing it, or accessing individual objects in it. Instead, it refers to the JSON-LD and JSON-LD API specifications for details on specific possible operations.

However, the JSON-LD specification simply defines the syntax and semantics of a JSON-LD, and does not say anything about how to access them, and of course neither should it, being just a specification of the format. I was expecting that kind of operation to be described in the JSON-LD API specification, but it only describes operations that convert the entire JSON-LD file into different forms (compact, expanded, flattening, and conversion to RDF). It does not seem to include operations for accessing the objects (for example, accessing the key-value pairs of an object).

So I am guessing we are supposed to read the JSON-LD file and expand or flatten it, and then access it as pure JSON. But JSONLD-JAVA methods only return instances of Object, so it's not clear to me how I can use these object to obtain the JSON key-value pairs. The only exception seems to be the method frame, which returns a Map, but it is not very clear to me what a frame is. The JSON-LD specification does not include the word "frame", and the JSON-LD API specification has a very terse explanation which does not seem to help in understanding how to access an object's key-value pairs.

The fact that I only have Object instances from JSONLD-JAVA methods also makes it look like it would be hard to use some JSON library to use them, unless I use some JSON library that knows about the internal format of these objects as formed by JSONLD-JAVA, but the page of JSONLD-Java does not mention any such library.

I was expecting to be able to read a JSON-LD file and then programmatically accessing or manipulating it within Java, and to have Java classes that correspond to the main concepts, something like a JSONLDObject with methods for providing its key-value pairs.

As I read the above pages, I get the feeling that they are meant for people that already know something that I don't. So perhaps I am missing something. Otherwise, is there a tutorial on using JSONLD-JAVA or even just the JSONLD API in order to traverse the objects?

user118967
  • 4,895
  • 5
  • 33
  • 54

2 Answers2

4

If you read the documentation on the JSONLD-JAVA page you linked to, it starts with a commented example:

// Open a valid json(-ld) input file
InputStream inputStream = new FileInputStream("input.json");
// Read the file into an Object (The type of this object will be a List, Map, String, Boolean,
// Number or null depending on the root object in the file).
Object jsonObject = JsonUtils.fromInputStream(inputStream);
// Create a context JSON map containing prefixes and definitions
Map context = new HashMap();
// Customise context...
// Create an instance of JsonLdOptions with the standard JSON-LD options
JsonLdOptions options = new JsonLdOptions();
// Customise options...
// Call whichever JSONLD function you want! (e.g. compact)
Object compact = JsonLdProcessor.compact(jsonObject, context, options);
// Print out the result (or don't, it's your call!)
System.out.println(JsonUtils.toPrettyString(compact));

The second comment is interesting, so let me highlight it for you:

Read the file into an Object (The type of this object will be a List, Map, String, Boolean, Number or null depending on the root object in the file).

Object jsonObject = JsonUtils.fromInputStream(inputStream);

The key point is that JSONLD is JSON, and that when you've loaded it into memory like above, you can navigate that JSON structure, by casting the Object as appropriate.

Lets have a look at Example #3 from the JSON-LD specification:

{
  "@context":
  {
    "name": "http://schema.org/name",  // ← This means that 'name' is shorthand for 'http://schema.org/name' 
    "image": {
      "@id": "http://schema.org/image",  // ← This means that 'image' is shorthand for 'http://schema.org/image' 
      "@type": "@id"  // ← This means that a string value associated with 'image' should be interpreted as an identifier that is an IRI 
    },
    "homepage": {
      "@id": "http://schema.org/url",  // ← This means that 'homepage' is shorthand for 'http://schema.org/url' 
      "@type": "@id"  // ← This means that a string value associated with 'homepage' should be interpreted as an identifier that is an IRI 
    }
  }
}

So if you want the @id value of the image, you'd do this:

Map<String, Object> root = (Map) jsonObject;
Map<String, Object> context = (Map) root.get("@context");
Map<String, Object> image = (Map) root.get("image");
String imageId = (String) image.get("@id");
Community
  • 1
  • 1
Andreas
  • 154,647
  • 11
  • 152
  • 247
2

1. Convert JSON-LD to a nice nested map. Use the framing algorithm. Example: JSON-LD to normal JSON and How to convert RDF to pretty nested JSON using java rdf4j

2. Accessing JSON-LD. I would use JsonNode together with JPointer. On small and simple documents operating directly on the Map<String,Object> is also ok. For JsonPointer you can use Jackson JsonNode.at().

ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readValue(in, JsonNode.class);
String id = json.at("/@id").getText();

3. Preprocessing. In some cases it can be handy to preprocess the JSON Input. This answer lists some command line tools: XSLT equivalent for JSON

Community
  • 1
  • 1
jschnasse
  • 8,526
  • 6
  • 32
  • 72