2011-11-06 12 views
6

Co mam Mam szablony, które są przechowywane w bazie danych, oraz dane JSON, które są konwertowane na słownik w języku C#.Jakie podejście do szablonów w C# powinienem wziąć?

Przykład:

Szablon: "Cześć {FirstName}"

danych: "{Imię: 'Jack'}"

Działa to łatwo z jednego poziomu danych za pomocą wyrażenia regularnego wyciągnąć wszystko z {} w szablonie.

Co chcę Chciałbym móc wejść głębiej w JSON niż pierwsza warstwa.

Przykład:

Szablon: "Cześć {Imię: {Pierwszy}}"

danych: "{Nazwa: {pierwsze: 'Jack', Last: 'Smith'}}"

Jakie podejście powinienem przyjąć? (I pewne wskazówki, gdzie zacząć wybierać)

  1. wyrażenia regularnego
  2. Nie używać JSON w szablonie (za XSLT lub coś podobnego)
  3. coś innego

Chciałbym również móc przeglądać dane w szablonie, ale nie mam pojęcia, od czego zacząć!

Dzięki hałdy

Odpowiedz

2

Oto jak zrobiłbym to:

zmienić szablon do tego formatu Hi {Name.First}

Teraz utworzyć JavaScriptSerializer do konwersji JSON w Dictionary<string, object>

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

teraz zmienna d ma wartości swojej JSON w słowniku.

Po tym można uruchomić szablon z wyrażeniem regularnym, aby zastąpić {X.Y.Z.N} kluczami słownika, rekursywnie.

Pełna Przykład:

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; 
     }); 
} 

nie obsługiwać wyjątki (np wartość nie udało się znaleźć), można obsługiwać tę sprawę i zwróci dopasowaną wartość, jeśli nie został znaleziony. m.Value dla wartości nieprzetworzonej lub m.Groups[1].Value dla ciągu znaków między {}.

2

Czy myślałeś o użyciu JavaScript jako język skryptowy? Miałem wielki sukces z Jint, chociaż koszt uruchomienia jest wysoki. Inną opcją jest Jurassic, której sam nie wykorzystałem.

Jeśli masz aplikację sieciową, możesz skorzystać z Razora, see here.

Używanie Regex lub jakikolwiek rodzaj analizowania ciągów może z pewnością działać dla trywialnych rzeczy, ale może stać się bolesny, gdy chcesz logiki, a nawet tylko podstawowych hierarchii. Jeśli deserializowania swoją JSON do zagnieżdżonych słowniki, można zbudować parser stosunkowo łatwo:

// 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()]; 

Wystarczy cokolwiek robisz, nie rób XSLT. Naprawdę, jeśli XSLT jest odpowiedź to pytanie musiało być naprawdę zdesperowany :)

+0

To brzmi jak idealny scenariusz dla XSLT. –

+0

Tylko jeśli podoba ci się gadatliwość, którą przynosi ze sobą. –

+0

Mój szef zgodziłby się z tobą, Kirk, ale jak mówi Michael, jest to trochę za duże dla tego, co próbuję zrobić. I dzięki Michaelowi, twoja odpowiedź jest również świetna, ale może dać tylko jeden tyk :) –

4

Masz szczęście! SmartFormat robi dokładnie to, co opisujesz. Jest to lekkie narzędzie do formatowania ciągów z otwartym kodem źródłowym.

Obsługuje nazwanych zastępcze:

var template = " {Name:{Last}, {First}} "; 

var data = new { Name = new { First="Dwight", Last="Schrute" } }; 

var result = Smart.Format(template, data); 
// Outputs: " Schrute, Dwight " SURPRISE! 

Obsługuje również lista formatowania:

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 " 

Możesz sprawdzić testy jednostkowe dla Named Placeholders i List Formatter zobaczyć dużo więcej przykładów!

Posiada nawet kilka form obsługi błędów (ignorowanie błędów, błędów wyjściowych, błędów rzutowania).

Uwaga: nazwie zastępczy funkcja wykorzystuje odbicia i/lub słownika wyszukiwań, dzięki czemu można deserializować JSON w C# obiektów lub zagnieżdżone Dictionaries, i będzie działać świetnie!

Powiązane problemy