json-ld-api icon indicating copy to clipboard operation
json-ld-api copied to clipboard

Recursively nested properties and compaction

Open pchampin opened this issue 5 years ago • 7 comments

Following the discussion in #380, I have a question:

Consider the following data:

{
  "@context": {
    "foo": "http://example.org/foo",
    "bar": "http://example.org/bar",
    "baz": "http://example.org/baz",
    "n1": "@nest",
    "n2": "@nest"
  },
  "foo": "FOO",
  "n1": {
    "bar": "BAR",
    "n2": {
      "baz": "BAZ"
    }
  }
}

Can I expand it and compact it back to the same shape (including the doubly-nested property baz)?

I gave it a try there but with no luck.

If this is indeed impossible, I'm not suggesting we should fix it now. But I'm trying to decide how bad it is if we introduce an asymmetry between expansion and compaction wrt nested properties in #388. If it appears that the asymetry is already there (in the example above), that would help be byte the bullet.

pchampin avatar Feb 25 '20 09:02 pchampin

I attempted a similar thing, and I think it could, in theory, only work by declaring one of the nests as nested within the other, e.g.:

    "n1": "@nest",
    "n2": {"@id": "@nest", "@nest": "n1"}

But the compaction algorithm doesn't support that.

niklasl avatar Feb 25 '20 10:02 niklasl

No, one level only. Basically, when compacting, we match to the term "baz" and see that it is nested on "n2". There is nothing to say that "n2" is, itself, nested under "n1".

In theory, (but I don't believe in practice), you might use the following context:

{
  "@context": {
    "foo": "http://example.org/foo",
    "bar": {"@id": "http://example.org/bar", "@nest": "n1"},
    "baz": {"@id": "http://example.org/baz", "@nest": "n2"},
    "n1": "@nest",
    "n2": {"@id": "@nest", "@nest": "n1"}
  },
  "foo": "FOO",
  "n1": {
    "bar": "BAR",
    "n2": {
      "baz": "BAZ"
    }
  }
}

But, the processing rules don't allow that.

gkellogg avatar Feb 25 '20 17:02 gkellogg

This issue was discussed in a meeting.

  • RESOLVED: Defer #391 on recursively nested properties to future version as new feature that can be experimented with
View the transcript Recursive Nesting and Compaction
Rob Sanderson: https://github.com/w3c/json-ld-api/issues/391
Rob Sanderson: Next one is related by pchampin.
Pierre-Antoine Champin: This issue is just to check that recursively nested properties are … after round-tripping.
… I didn’t suggest any change. This can be closed. This was just to support my other arguments in the previous issue.
Gregg Kellogg: We should also defer this, rather than close.
Proposed resolution: Defer #391 on recursively nested properties to future version as new feature that can be experimented with (Rob Sanderson)
Gregg Kellogg: +1
Rob Sanderson: +1
Pierre-Antoine Champin: +1
David I. Lehn: +1
Ruben Taelman: +1
Tim Cole: +1
Harold Solbrig: +1
Resolution #2: Defer #391 on recursively nested properties to future version as new feature that can be experimented with
3.

iherman avatar Feb 28 '20 18:02 iherman

Hello, What could I do if I must have Recursively nested properties in my json-ld, is there a workaround or a trick :)? Thanks

{
   "data": {
            "value": "TestValue",
            "nameType": {
                "testKey": "testValue",
                "name": "TestName"
            }
        }
}

MajdT51 avatar Feb 08 '23 14:02 MajdT51

@MajdT51 without a context in your data, and a description of what you are trying to achieve with it, it is hard to understand exactly what you question is...

pchampin avatar Feb 08 '23 16:02 pchampin

@MajdT51 without a context in your data, and a description of what you are trying to achieve with it, it is hard to understand exactly what you question is...

Thanks @pchampin , I'm working on verifiable credentials with json-ld and the credential subject has a complex object with recursive nested data. This is an example on the content of my credential subject

{
   "data": {
            "value": "TestValue",
            "nameType": {
                "testKey": "testValue",
                "name": "TestName"
            }
        }
}

So basically it is a recursive nested object "nameType" inside object "data". And I'm using this context https://api.npoint.io/f825bb32e1f3bda88b85 ->

{
  "@context": {
    "ctx": "https://mydomain/selfdescription#",
    "@version": 1.1,
    "@protected": true,
    "NameCredential": {
      "@id": "ctx:NameCredential",
      "@context": {
        "data": "@nest",
        "value": {
          "@id": "ctx:value",
          "@nest": "data"
        },
        "nameType": {
          "@id": "ctx:nameType",
          "@nest": "data",
          "@context": {
            "name": {
              "@id": "ctx:name",
              "@nest": "nameType"
            },
            "testKey": {
              "@id": "ctx:testKey",
              "@nest": "nameType"
            }
          }
        }
      }
    }
  }
}

However, it is seems not to be valid and pyld shows me this error JSON-LD compact error; nested property must have an @nest value resolving to @nest.( https://github.com/digitalbazaar/pyld/blob/master/lib/pyld/jsonld.py#L3353) I think it is because nameType must be " @ nest" similar to "data"

As I understood this is not possible now with json-ld 1.1 :( is this correct and are there any workarounds?

MajdT51 avatar Feb 08 '23 16:02 MajdT51

the two lines "@nest": "nameType" is not necessary in your context. As part of a scoped context, those properties (name and testKey) will only be used on values of nameType, so they will be "nested" the way you want.

pchampin avatar Feb 08 '23 16:02 pchampin