Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define JSON-LD @context to join/split values?

I'd like to use the expand and compact methods of the jsonld.js library to translate data from various sources into a common format for processing. If I take a source JSON document, add a @context to it, then pass it through the expand method I'm able to get the common format that I need.

The use case that I haven't been able to find a solution for is when multiple values need to be merged. For example, schema.org defines a PostalAddress with a single field for the streetAddress, but many systems store the street address as separate values (street number, street name, street direction...). To translate the incoming data to the schema.org format I need a way to indicate in my @context that multiple fields make up the streetAddress, in the correct order.

Compacted Document

{
    "@context": {
        "displaName": "http://schema.org/name",
        "website": "http://schema.org/homepage",
        "icon": "http://schema.org/image",
        "streetNumber": "http://schema.org/streetAddress"
    },
    "displaName": "John Doe",
    "website": "http://example.com/",
    "icon": "http://example.com/images/test.png",
    "streetNumber": "123",
    "streetName": "Main St",
    "streetDirection": "South"
}

Expanded Document

{
   "http://schema.org/name":[
      {
         "@value":"John Doe"
      }
   ],
   "http://schema.org/image":[
      {
         "@value":"http://example.com/images/test.png"
      }
   ],
   "http://schema.org/streetAddress":[
      {
         "@value":"123"
      }
   ],
   "http://schema.org/homepage":[
      {
         "@value":"http://example.com/"
      }
   ]
}

I've reviewed all of the JSON-LD specs that I could find and haven't been able to locate anything that indicates a way to split or concatenate values using the @context.

Is anyone aware of a way to map multiple values into one context property, in the correct order, and possibly add whitespace between the values. I also need to find a solution for the reverse scenario, where I need to split one field into multiple values, in the correct order.

Note: Even if I map all three properties to streetAddress, the values will all be included in the array, but there's no guarantee they'll be in the correct order.

like image 557
Brian Shamblen Avatar asked Oct 21 '15 22:10

Brian Shamblen


People also ask

What is @context in JSON-LD?

JSON-LD introduces the concept of the @context element which provides additional information allowing the computer to interpret the rest of the data with more clarity and depth. Furthermore the JSON-LD specification enables you to define a unique @type associating a well-defined data model to the data itself.

What is the difference between JSON and JSON-LD?

JSON Schema is primarily used for describing large sets of self-contained data, used as a data descriptor it's similar to XML schema. JSON LD is a way to describe data use of the web, more similar to schema.org or meta descriptors. It's consumed for more than one type of object and can be used to discover schema.

What is @ID in JSON-LD?

JSON-LD supports references to objects with a reserved key @id which can be used either as an object identifier or a reference to an object identifier. The value of @id must be a string.

Can you have multiple Ld JSON?

Yes, it is totally fine to use both syntaxes side by side on the same page but Google will not be able to merge attributes for the same entity using the item ID unless you are using json-ld ONLY.


1 Answers

One possible way to achieve this is to use a single array field for your address containing the ordered address components (i.e. ["number", "direction", "name"]). Then in the @context you can specify the address with @container: @list, which will ensure the address components are correctly ordered.

So the compacted document would be:

{
    "@context": {
        "displaName": "http://schema.org/name",
        "website": "http://schema.org/homepage",
        "icon": "http://schema.org/image",
        "address": {
          "@id": "http://schema.org/streetAddress",
          "@container": "@list"
        }
    },
    "displaName": "John Doe",
    "website": "http://example.com/",
    "icon": "http://example.com/images/test.png",
    "address": ["123", "South", "Main St"]
}

And the expanded one would be

  {
    "http://schema.org/streetAddress": [
      {
        "@list": [
          {
            "@value": "123"
          },
          {
            "@value": "South"
          },
          {
            "@value": "Main St"
          }
        ]
      }
    ],
    "http://schema.org/name": [
      {
        "@value": "John Doe"
      }
    ],
    "http://schema.org/image": [
      {
        "@value": "http://example.com/images/test.png"
      }
    ],
    "http://schema.org/homepage": [
      {
        "@value": "http://example.com/"
      }
    ]
  }
like image 77
Val Avatar answered Oct 09 '22 12:10

Val