What approach to templates in C # should I take?

What I have I have templates that are stored in the database, and JSON data that is converted to a C # dictionary.

Example:

Template: "Hello {FirstName}"

Data: "{FirstName: 'Jack'}"

This easily works with one level of data, using a regular expression to pull something inside {} in the template.

What I want I would like to be able to go deeper in JSON than in the first layer.

Example:

Template: "Hello {Name: {First}}"

Data: "{Name: {First: 'Jack', Last: 'Smith'}}"

Which approach should I take? (and some tips on where to start with your choice)

  • Regular expression
  • Do not use JSON in the template (in favor of xslt or something similar)
  • Something else

I would also like to be able to scroll through the data in the template, but I have no idea where to start from this!

Thanks heaps

+6
source share
4 answers

Here's how I do it:

Change your template in this format Hi {Name.First}

Now create a JavaScriptSerializer to convert JSON to Dictionary<string, object>

 JavaScriptSerializer jss = new JavaScriptSerializer(); dynamic d = jss.Deserialize(data, typeof(object)); 

Now the variable d has the values โ€‹โ€‹of your JSON in the dictionary.

After that, you can run the pattern against the regular expression to replace {XYZN} with dictionary keys, recursively.

Full example:

 public void Test() { // Your template is simpler string template = "Hi {Name.First}"; // some JSON string data = @"{""Name"":{""First"":""Jack"",""Last"":""Smith""}}"; JavaScriptSerializer jss = new JavaScriptSerializer(); // now `d` contains all the values you need, in a dictionary dynamic d = jss.Deserialize(data, typeof(object)); // running your template against a regex to // extract the tokens that need to be replaced var result = Regex.Replace(template, @"{?{([^}]+)}?}", (m) => { // Skip escape values (ex: {{escaped value}} ) if (m.Value.StartsWith("{{")) return m.Value; // split the token by `.` to run against the dictionary var pieces = m.Groups[1].Value.Split('.'); dynamic value = d; // go after all the pieces, recursively going inside // ex: "Name.First" // Step 1 (value = value["Name"]) // value = new Dictionary<string, object> // { // { "First": "Jack" }, { "Last": "Smith" } // }; // Step 2 (value = value["First"]) // value = "Jack" foreach (var piece in pieces) { value = value[piece]; // go inside each time } return value; }); } 

I did not handle exceptions (for example, the value could not be found), you can handle this case and return the associated value if it was not found. m.Value for the original value or m.Groups[1].Value for the line between {} .

+2
source

What a score! SmartFormat does exactly what you describe. This is an easy open source string formatting utility.

It supports named placeholders :

 var template = " {Name:{Last}, {First}} "; var data = new { Name = new { First="Dwight", Last="Schrute" } }; var result = Smart.Format(template, data); // Outputs: " Schrute, Dwight " SURPRISE! 

It also supports list formatting:

 var template = " {People:{}|, |, and} "; var data = new { People = new[]{ "Dwight", "Michael", "Jim", "Pam" } }; var result = Smart.Format(template, data); // Outputs: " Dwight, Michael, Jim, and Pam " 

You can check the unit tests for Named Placeholders and List Formatter to see many examples!

It even has several forms of error handling (ignores errors, displays errors, throws errors).

Note. A function called placeholder uses reflection and / or dictionary lookups, so you can deserialize JSON to C # objects or nested Dictionaries , and it will work just fine!

+4
source

Have you considered using Javascript as a scripting language? I had great success with Jint , although the starting cost is high. Another option is Jurassic , which I have not used myself.

If you have a web application, use Razor, perhaps the idea is here .

Using Regex or any kind of string parsing can certainly work for trivial things, but can be painful when you want logic or even just basic hierarchies. If you deserialize your JSON into nested dictionaries, you can easily build a parser:

 // Untested and error prone, just to illustrate the concept var parts = "parentObj.childObj.property".split('.'); Dictionary<object,object> current = yourDeserializedObject; foreach(var key in parts.Take(parts.Length-1)){ current = current[key]; } var value = current[parts.Last()]; 

Whatever you do, do not do XSLT. Indeed, if XSLT is the answer, then the question should be really desperate :)

+2
source

Why don't we have nvelocity or something else?

+1
source

Source: https://habr.com/ru/post/900863/


All Articles