-
Notifications
You must be signed in to change notification settings - Fork 235
Description
I have this test json:
{ "partyEvent": { "partyName": "Sweet Treats Fiesta", "day": "Saturday", "hour": "5:00 PM", "date": "2024-09-28", "address": { "street": "123 Party Lane", "city": "Funville", "state": "CA", "zip": "90210" }, "theme": "Desserts Extravaganza", "host": { "name": "Jane Doe", "contact": "[email protected]" }, "participants": [ { "name": "Alice Smith", "role": "Guest", "RSVP": true }, { "name": "John Johnson", "role": "Guest", "RSVP": false }, { "name": "Emily Davis", "role": "Caterer", "RSVP": true } ], "menu": { "items": [ { "id": "0001", "type": "donut", "name": "Cake", "ppu": 0.55, "batters": { "batter": [ { "id": "1001", "type": "Regular" }, { "id": "1002", "type": "Chocolate" }, { "id": "1003", "type": "Blueberry" }, { "id": "1004", "type": "Devil's Food" } ] }, "topping": [ { "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5005", "type": "Sugar" }, { "id": "5007", "type": "Powdered Sugar" }, { "id": "5006", "type": "Chocolate with Sprinkles" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] }, { "id": "0002", "type": "donut", "name": "Raised", "ppu": 0.55, "batters": { "batter": [ { "id": "1001", "type": "Regular" } ] }, "topping": [ { "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5005", "type": "Sugar" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] }, { "id": "0003", "type": "donut", "name": "Old Fashioned", "ppu": 0.55, "batters": { "batter": [ { "id": "1001", "type": "Regular" }, { "id": "1002", "type": "Chocolate" } ] }, "topping": [ { "id": "5001", "type": "None" }, { "id": "5002", "type": "Glazed" }, { "id": "5003", "type": "Chocolate" }, { "id": "5004", "type": "Maple" } ] } ] } } }
And I want to convert it to this one:
{ "eventoFesta": { "nomeFesta": "Sweet Treats Fiesta", "giorno": "Saturday", "ora": "5:00 PM", "data": "2024-09-28", "indirizzo": { "via": "123 Party Lane", "città": "Funville", "stato": "CA", "cap": "90210" }, "tema": "Desserts Extravaganza", "ospite": { "nome": "Jane Doe", "contatto": "[email protected]" }, "personeInvitate": { "partecipanti": [ { "nome": "Alice Smith", "ruolo": "Guest", "RSVP": true }, { "nome": "John Johnson", "ruolo": "Guest", "RSVP": false }, { "nome": "Emily Davis", "ruolo": "Caterer", "RSVP": true } ] } } }
through this template that it will simply map the first one through the second one:
var template = """ { "eventoFesta": { "nomeFesta": "{{jsonpath '$.partyEvent.partyName'}}", "giorno": "{{jsonpath '$.partyEvent.day'}}", "ora": "{{jsonpath '$.partyEvent.hour'}}", "data": "{{jsonpath '$.partyEvent.date'}}", "indirizzo": { "via": "{{jsonpath '$.partyEvent.address.street'}}", "città": "{{jsonpath '$.partyEvent.address.city'}}", "stato": "{{jsonpath '$.partyEvent.address.state'}}", "cap": "{{jsonpath '$.partyEvent.address.zip'}}" }, "tema": "{{jsonpath '$.partyEvent.theme'}}", "ospite": { "nome": "{{jsonpath '$.partyEvent.host.name'}}", "contatto": "{{jsonpath '$.partyEvent.host.contact'}}" }, "personeInvitate": { "partecipanti": [ {{#each (jsonpath '$.partyEvent.participants')}} { "nome": "{{jsonpath '$.name'}}", "ruolo": "{{jsonpath '$.role'}}", "RSVP": {{jsonpath '$.RSVP'}} }{{#unless @last}},{{/unless}} {{/each}} ] } } } """;
Since we are dealing with JSON, I wrote an helper, which is "jsonpath":
`
using HandlebarsDotNet;
using Json.Path;
using System.Text.Json.Nodes;
namespace _01_BaseSKStuff.BaseUtils.JsonUtils
{
internal static class PathEvaluator
{
internal static HandlebarsHelper PathTrasversalHelper => (writer, context, parameters) =>
{
if (parameters.Length == 0)
{
writer.Write(null);
return;
}
var data = JsonNode.Parse(context.Value.ToString());
var paramValue = parameters[0].ToString();
if (data is null || paramValue is null)
{
writer.Write(null);
return;
}
var value = EvaluatePath(data, paramValue);
writer.Write(value);
};
public static string? EvaluatePath(JsonNode jsonNode, string rulePath)
{
var jsonPath = JsonPath.Parse(rulePath);
var pathResult = jsonPath.Evaluate(jsonNode);
if (pathResult is null || pathResult.Matches.Count != 1) return null;
return pathResult.Matches.Select(x => x.Value?.ToString()).First();
}
}
}
`
This just takes the first element of a json path, traversing it with the syntax "$.thisproperty.thischildproperty"
It actually maps everything good except for the #each helper that does not seem to like what it returns, which is a JsonArray[].
How to make this work?