Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying to devise a document system for a specific domain involving simple objects (People, Companies, Invoices, etc.) that would also be able to completely describe itself. This self-description ability would ideally be recursive. The document system will be based on JSON, but I believe the principle in question applies to any structured notation.

To illustrate what I mean, let's say I have the following JSON document that describes a person (company, invoice, etc. are basically all the same, only with different properties):

{
  "Name": "John Doe",
  "Email": "john.doe@example.org",
  "BirthDate": "1976-07-04"
}

Then, I have a second JSON document that describes the structure of the first one. Let's call this a "Level 1 Meta-document":

{
  "Type": "Person",
  "Properties": {
    "Name": { "Type": "String", "Required": true },
    "Email": { "Type": "String" },
    "BirthDate": { "Type": "Date" }
  }
}

This would be simple enough, if not for the requirement, that system should also be able to fully describe this meta-document.

To put it in more general terms: I'm looking for a way to define a self-sufficient "Level N Meta-document", that would be able to describe a structure of the "Level N-1 Meta-documents".

NOTE: I'd be willing to go with a solution for N = 2, but instinct tells me that a true solution for N = 2 would also work for any N. Now that I think of it, this may be more of a math puzzle than programming one. :)

Is this even possible? If yes, can you give me some examples? If not, what are my other options?

EDIT: I've included a naive example of how a "Level 2 Meta-Document" would look, based on the above:

{
  "Type": "MetaLevel2",
  "Properties": {
    "Properties": { "Type": "Hash", "Required": true }
  }
}

The problem with this is that it doesn't describe the object that describes the property details (i.e. the one with the "Type" and "Required" attributes).

If I were to include description of those, I'd have to add another attribute to the very same object I'm trying to describe:

{
  "Type": "MetaLevel2",
  "Properties": {
    "Properties": {
      "Type": "Hash",
      "Required": true,
      "ValueProperties": { "Type": "String", "Required": "Boolean" }
    }
  }
}

Unfortunately, this throws me into recursive problem, because I now lack the description for "ValueProperties". In fact, for every new attribute I invent on level N, I have a problem describing it on level N+1 without introducing yet another attribute that needs description.

What I'm looking for is a solution that wouldn't suffer from this problem.

To be clear: I'm aware of XSD, but I'm not sure how to apply its principles to my case. Unless I'm missing something, XSD would suffer from the same recursive problem. This gives me reason to believe I have a problem with the approach itself.

share|improve this question
    
Nothing really new here: Meta-document=XML DTD=class, document=XML file=instance. I don't get what the actual question is. –  Tibo Mar 23 '13 at 10:27
    
@Tibo: I've edited the question to illustrate the point where I run into problems. While I sort of agree with what you mention, I fail to understand how this can help me. An example would be greatly appreciated! –  aoven Mar 23 '13 at 11:25
    
Ok, now I understand your question. Btw I meant XSD, not DTD. I'll try to phrase a proper answer. –  Tibo Mar 23 '13 at 12:20

3 Answers 3

There's IETF draft for JSON Schema. That sounds like what you want to use. Also check it out at Wikipedia.

share|improve this answer

Yes, this is possible. This is already used for XML and is called XML Schema Definition (XSD).

You may simply take what XSD does and do the same thing with JSON.

share|improve this answer
    
Oh, if only I could see how to do that! :) Please consider my edited question. Perhaps it better illustrates the exact problem I'm having. Thanks! –  aoven Mar 23 '13 at 11:27
up vote 0 down vote accepted

It seems I've now come up with a better approach. The recursion problem can be avoided by flattening the nested objects, like this:

{
  "Type": "MetaLevel2",
  "Properties": {
    "Properties": { "Type": "Hash", "Required": true },
    "Properties.Type": { "Type": "String", "Required": true },
    "Properties.Required": { "Type": "Boolean" }
  }
}

Granted, it feels like a slight abuse of the property system, but not unreasonably so. I can build the required awareness about the dotted property name notation directly into the software that will handle these documents.

I'll leave the question open for a while longer. Unless someone comes up with a cleaner solution during that time, I'll go with this.

EDIT: Yep, this works quite well, as it turns out.

Whenever I decide I need another nested attribute, I can simply describe it by using the flattened notation, thus staying compatible with existing structure.

The only special thing that software needs to understand to consume these documents is the meaning of "Type": "Hash" attribute, which signals that several attributes should be interpreted as a single JSON object when reading and vice-versa when writing.

Still, my thanks to everyone that took the time to read all this and respond!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.