2

JSON Schema:

{
   "title": "Amenities",
   "additionalProperties": false,
   "properties": {
      "Footer": {
         "type": "string",
         "editType": "textarea"
      },
      "RowType": {
         "type": "integer",
         "editType": null
      },
      "answers": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "answer": {
                        "type": "integer",
                        "editType": null
                    },
                    "FooterInner": {
                     "type": "string",
                     "editType": "textarea"
                  }
                }
            }
        }
   },
   "type": "object"
}

JSON Object:

{
   "Footer": "",
   "RowType": 0,
   "answers": [
      {
         "answer": 1,
         "FooterInner": "innerfooter"
      },
      {
         "answer": 2,
         "FooterInner": "innerfooter2"
      }
   ]
}

I need to find properties with "type=integer" in JSON Schema and remove those properties from JSON Object.

Expected JSON Object is:

{
   "Footer": "",
   "answers": [
      {
         "FooterInner": "innerfooter"
      },
      {
         "FooterInner": "innerfooter2"
      }
   ]
}

JSON Schema and JSON Objects may differ, so I need to validate and remove "type=integer" properties from any type of JSON Object.

I have searched and could not find something useful, and the main problem is there can be multiple nested elements in JSON.

Might be I need to write recursive iterating function, is there any existing solution?

6
  • have a look at Remove specific properties from JSON object it might help. Commented Mar 21, 2019 at 9:23
  • I have already looked at this question, thanks. My problem is JSON schema and JSON objects may differ every time, so I can not deserialize them to any class. Commented Mar 21, 2019 at 9:25
  • What you're asking is similar to asking "Can I make my car drive in water?" - Well yes, but you're going to have to do significant modifications, so you may just as well buy a boat rather than a car. JSON Schema isn't designed to do what you're asking here, so you'll have to write the code to do that yourself. Commented Mar 21, 2019 at 10:06
  • 1
    Apologies if my comment came across wrong. I was trying to express why I feel the answer to your question is "There's no out of the box functionality, you need to write code to do this." I don't feel that sort of answer is always helpful as a SO answer. - I comment on as many JSON Schema questions as I feel may be helpful, given I work on the JSON Schema specification itself. Commented Mar 21, 2019 at 11:19
  • 1
    Thank you for your kind response. Now I'm trying to do it with recursive function, I will share my solution once I get it work Commented Mar 21, 2019 at 14:13

2 Answers 2

2

Here is the solution:

Instead of searching "type=integer" properties in schema I did it in JSON object.

But, firstly I validated JSON object against the JSON schema to be sure that there is no any additional property in JSON object.

1.Step - Validating JSON Object against JSON Schema:

JsonValue loadedSchema = JsonValue.Parse(jsonSchema);
var schema = JsonSchemaFactory.FromJson(loadedSchema);
JsonValue loadedObject = JsonValue.Parse(json);
var schemaValidationResult = schema.Validate(loadedObject);

If 1.Step is OK then execute 2.Step

2.Step - Remove Integer, Boolean and Float type properties from JSON Object:

static void Main(string[] args)
{
    var json =
        @"{
           ""Footer"": ""footer"",
                ""RowType"": 4,
                ""answers"": 
                [
                    {
                        ""answer"": 1,
                        ""FooterInner"": ""innerfooter""
                    },
                    {
                        ""answer"": 2,
                        ""FooterInner"": ""innerfooter2""
                    }
                ]
            }";
    JToken nodeList = JToken.Parse(json);
    List<JTokenType> typesToRemove = new List<JTokenType>(){JTokenType.Boolean, JTokenType.Float, JTokenType.Integer};

    removeFields(nodeList, typesToRemove);

    Console.WriteLine(nodeList.ToString());
    Console.ReadKey();
}

private static void removeFields(JToken token, List<JTokenType> typesToRemove)
{
    JContainer container = token as JContainer;
    if (container == null) return;

    List<JToken> removeList = new List<JToken>();
    foreach (JToken el in container.Children())
    {
        JProperty p = el as JProperty;
        if (p != null && typesToRemove.Contains(p.Value.Type))
        {
            removeList.Add(el);
        }

        removeFields(el, typesToRemove);
    }

    foreach (JToken el in removeList)
    {
        el.Remove();
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

So in your example code, is RowType and answers removed?
@Relequestual yes, integer type properties removed.
0

I think you have 2 options here:

  1. Write a custom json converter (see Custom Deserialization using Json.NET).
  2. Use dynamic objects (Jobjects, JTokens) with json.net.

2 Comments

Can you share some example code according to my JSON schema and object?
if you want to use the converter, the link has contains en example (answer). I guess your JsonObject represents the properties object. So you need to use the JsonConverter Attribute.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.